Back end - letronghieu4897/magento GitHub Wiki

Back-end

Back-end


1.Install Database or Schema

1.1 Create folder Setup

  • app/code/[Vendor]/[Extention]/Setup

1.2 Insert Data into Database

  • Create file : InstallData.php
  • Create Schema or Insert New Column : InstallSchema.php
<?php
namespace Netpower\Ghn\Setup;
use \Magento\Framework\Setup\InstallSchemaInterface;
use \Magento\Framework\Setup\SchemaSetupInterface;
use \Magento\Framework\Setup\ModuleContextInterface;
use \Magento\Framework\DB\Ddl\Table;

class InstallSchema implements InstallSchemaInterface
{

	public function install(SchemaSetupInterface $setup,ModuleContextInterface $context)
	{
		$installer = $setup;
		$installer->startSetup();

		if (!$installer->tableExists('[table_name]')) {
			$table = $installer->getConnection()->newTable(
				$installer->getTable('[table_name]')
			)
				->addColumn(
					'district_id',
					Table::TYPE_INTEGER,
					null,
					[
						'identity' => true,
						'nullable' => false,
						'primary'  => true,
						'unsigned' => true,
					],
					'District ID'
				)->addColumn(
					'name',
					Table::TYPE_TEXT,
					null,
					['nullable' => false],
					'District Name'
				)->addColumn(
					'region_id',
					Table::TYPE_INTEGER,
					null,
					['nullable' => false,
						'unsigned' => true,
					],
					'Region ID'
				)->addColumn(
					'province_id',
					Table::TYPE_INTEGER,
					null,
					['nullable' => false],
					'Province ID'
				)->addColumn(
					'district_number',
					Table::TYPE_INTEGER,
					null,
					['nullable' => false],
					'District Number'
				)->addForeignKey(
      		$installer->getFkName('[table_name]', 'region_id', '[table_name (foreign key) ]', 'region_id'),
      'region_id',
      $installer->getTable('directory_country_region'),
      'region_id',
      Table::ACTION_CASCADE
			);
			$installer->getConnection()->createTable($table);
		}
	}
}
  • Go into Database. Search setup_module then DROP it.
  • [YOU SHOULD Delete only Module you want to upgrade or install in setup_module table]
  • [DELETE FROM setup_module WHERE module="<Name_Module>"]
  • Go to Server : php bin/magento setup:upgrade

2.Cron Job

$ CRON JOB
. _______________________________________________________________________
├── etc
│     └── crontab.xml	
├── Cron
│     └── FileName.php
. ________________________________________________________________________

2.1 Create \app\code[Vendor][Extention]\etc\crontab.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
	<group id="default">
		<job instance="[Vendor]\[Extention]\Cron\FileName" method="execute" name="netpower_ghn_cron">
			<schedule>* * * * *</schedule>
		</job>
	</group>
</config>
* * * * * *
| | | | | | 
| | | | | +-- Year              (range: 1900-3000)
| | | | +---- Day of the Week   (range: 1-7, 1 standing for Monday)
| | | +------ Month of the Year (range: 1-12)
| | +-------- Day of the Month  (range: 1-31)
| +---------- Hour              (range: 0-23)
+------------ Minute            (range: 0-59)
* * * * * *                         Each minute


59 23 31 12 5 *                     One minute  before the end of year if the last day of the year is Friday
									
59 23 31 DEC Fri *                  Same as above (different notation)


45 17 7 6 * *                       Every  year, on June 7th at 17:45


45 17 7 6 * 2001,2002               Once a   year, on June 7th at 17:45, if the year is 2001 or  2002


0,15,30,45 0,6,12,18 1,15,31 * 1-5 *  At 00:00, 00:15, 00:30, 00:45, 06:00, 06:15, 06:30,
                                    06:45, 12:00, 12:15, 12:30, 12:45, 18:00, 18:15,
                                    18:30, 18:45, on 1st, 15th or  31st of each  month, but not on weekends


*/15 */6 1,15,31 * 1-5 *            Same as above (different notation)


0 12 * * 1-5 * (0 12 * * Mon-Fri *) At midday on weekdays


* * * 1,3,5,7,9,11 * *              Each minute in January,  March,  May, July, September, and November


1,2,3,5,20-25,30-35,59 23 31 12 * * On the  last day of year, at 23:01, 23:02, 23:03, 23:05,
                                    23:20, 23:21, 23:22, 23:23, 23:24, 23:25, 23:30,
                                    23:31, 23:32, 23:33, 23:34, 23:35, 23:59


0 9 1-7 * 1 *                       First Monday of each month, at 9 a.m.


0 0 1 * * *                         At midnight, on the first day of each month


* 0-11 * * *                        Each minute before midday


* * * 1,2,3 * *                     Each minute in January, February or March


* * * Jan,Feb,Mar * *               Same as above (different notation)


0 0 * * * *                         Daily at midnight


0 0 * * 3 *                         Each Wednesday at midnight

2.2 Create file Cron : \app\code[Vendor][Extention]\Cron\FileName.php

<?php
namespace [Vendor]\[Extention]\Cron;

class Test 
{
   public function __construct() 
    {}
 
   public function execute()
   {
      //CODE HERE
   }
}

2.3 Create connect Cron on server :

$ crontab -e
#~ MAGENTO START
* * * * * /usr/bin/php /var/www/html/[Source Magento]/bin/magento cron:run | grep -v Ran jobs by schedule >> /var/www/html/[Source Magento]/var/log/magento.cron.log
* * * * * /usr/bin/php /var/www/html/[Source Magento]/update/cron.php >> /var/www/html/[Source Magento]/var/log/update.cron.log
* * * * * /usr/bin/php /var/www/html/[Source Magento]/bin/magento setup:cron:run >> /var/www/html/[Source Magento]/var/log/setup.cron.log
#~ MAGENTO END:

2.4 Run Crontab

$ php bin/magento cache:flush
$ php bin/magento cron:run --group="default"

//"default" is group declared in crontab.xml

2.5 Change crontab.xml time schedule

$ crontab -e  
$ php bin/magento cache:flush 
$ php bin/magento cron:run --group="default"

2.6 Check status CRON schedule

mysql> SELECT * FROM cron_schedule WHERE status = 'running';

3.Collection

3.1 Create Collection

$ COLLECTION
. _______________________________________________________________________
├── Model
|     ├── GhnOrder.php 				[1]
|     └── ResourceModel				
|		├── GhnOrder.php		[2]
|		└── GhnOrder 
|			└── Collection.php 	[3]
|
. ________________________________________________________________________
  • [1] \app\code[Vendor][Extention]\Model\GhnOrder.php
<?php
namespace [Vendor]\[Extention]\Model;

use Magento\Framework\Model\AbstractModel;
	
	/**
	 * Collection to get data from directory_country_region
	 */
    class GhnOrder extends AbstractModel
    {   
        protected function _construct()
        {
            $this->_init('[Vendor]\[Extention]\Model\ResourceModel\GhnOrder');
        }
    }
  • [2] \app\code[Vendor][Extention]\Model\ResourceModel\GhnOrder.php
<?php
namespace [Vendor]\[Extention]\Model\ResourceModel;
class GhnOrder extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
    /**
     * Define main table
     */
    protected function _construct()
    {
        $this->_init('sale_ghn_order', 'entity_id');   
	//here "sale_ghn_order" is table name and "entity_id" is the key
    }
}
  • [3] \app\code[Vendor][Extention]\Model\ResourceModel\GhnOrder\Collection.php
<?php

/**
* Ecommerce Resource Collection
*/
namespace [Vendor]\[Extention]\Model\ResourceModel\GhnOrder;

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection{
/**
* Resource initialization
*
* @return void
*/
protected function _construct(){
	$this->_init('[Vendor]\[Extention]\Model\GhnOrder', '[Vendor]\[Extention]\Model\ResourceModel\GhnOrder');
	}
}

3.2 Using Factory

  • Example
<?php
namespace Netpower\Ghn\Controller\Adminhtml\System;

use \Magento\Catalog\Model\Product\Visibility;

use Netpower\Ghn\Helper\GhnApi;
use Netpower\Ghn\Model\GetRegionIdFactory;
use Netpower\Ghn\Services\Transport;

use Netpower\Ghn\Services\Config;

class Button extends \Magento\Backend\App\Action
{   
    protected $_ghnApi;
    protected $_getRegionId;
    protected $_log;

    public function __construct(
        \Magento\Backend\App\Action\Context $context,
        GhnApi $ghnApi,
        GetRegionIdFactory $getRegionId,
        Transport $log
         
    ) { 
        $this->_ghnApi = $ghnApi;
        $this->_getRegionId = $getRegionId;
        $this->_log = $log;
        parent::__construct($context);
    }
    public function execute(){

        $token = Config::TOKEN_STAGING;
        $requestToken = array(
            'token' => $token
        );
        
        $requestTokens = json_encode($requestToken);
        $listDistrictProvinceArray = $this->_ghnApi->getDistrictProvince($requestTokens);

	/**********************************************************************
	 *			HERE IS FACTORY
	 **********************************************************************/
        $districts = $this->_getRegionId->create()->getCollection()->getData();

        $this->_log->log($districts);

        }
}
  • Get Data
 $getData = $this->_getRegionId->create()->getCollection()->getData();
  • Set Data
 $setData = $this->_getRegionId->create();
 $setData->setData([name_of_column], $data);
 $setData->save()
  • Load Data
$loadData = $this->_ghnOrder->create()->load(['name_of_column']);
  • Update Data
//Combine Set and Load Data

$loadData = $this->_ghnOrder->create()->load(['id_of_table']);

$loadData->setData([name_of_column], $data);
$loadData->save()

4.Get Data

4.1. From Admin Field

<?php
namespace Netpower\Ghn\Model;

use \Magento\Store\Model\ScopeInterface;

class Carrier extends AbstractCarrier implements CarrierInterface
{
/**
 * @var string
 */

/**
 * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
 * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
 * @param \Psr\Log\LoggerInterface $logger
 * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
 * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
 * @param \Netpower\Ghn\Controller\Getdata\Getdata $fee
 * @param array $data
 */
public function __construct(
    ScopeConfigInterface $scopeConfig, 
    array $data = []
)
{
    parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
}

/**
 * @return array
 */
public function getAllowedMethods()
{
    /*0*/
    return ['giaohangnhanh' => $this->getConfigData('name') ];
}

/**
 * Processing additional validation to check is carrier applicable.
 *
 * @param \Magento\Framework\DataObject $request
 * @return $this|bool|\Magento\Framework\DataObject
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
public function processAdditionalValidation(DataObject $request)
{
    /*1*/
    return $this;
}

/**
 * @param RateRequest $request
 * @return bool|Result
 */
public function collectRates(RateRequest $request)
{
    $adminField = $this->_scopeConfig->getValue('[id of section]/[id of group]/[id of field]', ScopeInterface::SCOPE_STORE);
}

5.Extension template path hints

- Copy Netpower Base
- Copy Netpower Backend
- Copy MagePsycho/Easypathhints

6.Controller

1. Create routes.xml 		: etc/routes.xml

2. Create <controller>.php 	: Controller/<Folder_Action>/<controller>.php
	EXAMPLE					: Controller/Testcontroller/Controllertest.php

routes.xml

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route frontName="netpowermomo" id="netpowermomo">
            <module name="Netpower_Momo"/>
        </route>
    </router>
</config>

Controller/Testcontroller/Controllertest.php

<?php

namespace Netpower\Momo\Controller\Testcontroller;

use \Magento\Framework\App\Action\Context; 

class Controllertest extends \Magento\Framework\App\Action\Action
{
    public function __construct(
        Context $context
        )
    {
        return parent::__construct($context);
    }

    public function execute()
    {
        echo "TEST";
    }

}

URL call Controller

- <caomoi.local>/netpowermomo/testcontroller/controllertest

6.1 Redirect to other page

...
..
.
public function execute() { 
	$resultRedirect = $this->resultRedirectFactory->create();
    $resultRedirect->setPath(<path_frontname>_<controller>_<action>); Example momo/index/success;
    return $resultRedirect;
}


.
..
...

7.Get data response and request

In Controller

$valueResponse = $this->getRequest()->getParams();

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
Controller extend \Magento\Framework\App\Action\Action  

So, we don't have to declare
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

In orther file

8.Session

\Magento\Checkout\Model\Session $_session;


$_session->setCaomoi("MOI"); 


YOU WANT TO GET IT : [$_session->getCaomoi()  = "MOI"]



WE HAVE SOME KIND OF SESSION SUCH AS

\Magento\Backend\Model\Session
\Magento\Catalog\Model\Session
\Magento\Checkout\Model\Session
\Magento\Customer\Model\Session
\Magento\Newsletter\Model\Session

9.Payment Redirect to Third Party Page

app/code/Test/Testpayment/view/frontend/web/js/view/payment/method-renderer/testpayment.js
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*browser:true*/
/*global define*/
define(
    [
        'ko',
        'jquery',
        'Magento_Checkout/js/view/payment/default',
        'Test_Testpayment/js/action/set-payment-method-action'
    ],
    function (ko, $, Component, setPaymentMethodAction) {
        'use strict';
        return Component.extend({
            defaults: {
                redirectAfterPlaceOrder: false,
                template: 'Test_Testpayment/payment/testpayment'
            },
            afterPlaceOrder: function () {
                setPaymentMethodAction(this.messageContainer);
                return false;
            }
        });
    }
);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
app/code/Test/Testpayment/frontend/web/js/action/set-payment-method-action.js
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*jshint jquery:true*/
define(
    [
        'jquery',
        'Magento_Checkout/js/model/quote',
        'Magento_Checkout/js/model/url-builder',
        'mage/storage',
        'Magento_Checkout/js/model/error-processor',
        'Magento_Customer/js/model/customer',
        'Magento_Checkout/js/model/full-screen-loader'
    ],
    function ($, quote, urlBuilder, storage, errorProcessor, customer, fullScreenLoader) {
        'use strict';
        return function (messageContainer) {
            $.mage.redirect(url); //url is your url
        };
    }
);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

10.Upgrade Schema to insert new column into existing table

1. Check version module  (/etc/module.xml)

2. Go to database -> table setup-module -> delete old version
Setup > UpgradeSchema
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
<?php
namespace Netpower\Momo\Setup;

use \Magento\Framework\Setup\UpgradeSchemaInterface;
use \Magento\Framework\Setup\ModuleContextInterface;
use \Magento\Framework\Setup\SchemaSetupInterface;

use \Magento\Framework\DB\Ddl\Table;

class UpgradeSchema implements UpgradeSchemaInterface
{
    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        if (version_compare($context->getVersion(), '<version_module> example 2.0.1>') < 0) {
        $setup->startSetup();
        $setup->getConnection()->addColumn(
        $setup->getTable('<table_name>'),
        '<column_name>',
        [
        'type' => Table::TYPE_INTEGER,
        'length' => '20',
        'unique' => true,
        'comment' => 'pla pla pla'
        ]);
        $setup->endSetup();
        }
    } 
} 

11.Flow change status Order Magento 2

Flow Order status

12.Create Constructor when Extend Class

PARENT CLASS 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
        \Magento\Payment\Helper\Data $paymentData,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Payment\Model\Method\Logger $logger,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, // OPTIONAL
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, // OPTIONAL
        array $data = [],	// OPTIONAL
        DirectoryHelper $directory = null	// OPTIONAL
    ) {
        parent::__construct(
            $context,
            $registry,
            $extensionFactory,
            $customAttributeFactory,
            $resource,
            $resourceCollection,
            $data
        );
        $this->_paymentData = $paymentData;
        $this->_scopeConfig = $scopeConfig;
        $this->logger = $logger;
        $this->directory = $directory ?: ObjectManager::getInstance()->get(DirectoryHelper::class);
        $this->initializeData($data);
    }
EXTEND CLASS (Child)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
public function __construct(
        \Magento\Framework\Model\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
        \Magento\Payment\Helper\Data $paymentData,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Payment\Model\Method\Logger $logger,
        \Magento\Directory\Helper\Data $directory,
        RefundOrder $refund,
        Transport $transport,
        MomoOrderFactory $momoOrderFactory,
        Config $config,
        \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null, // OPTIONAL
        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null, // OPTIONAL
        array $data = []	// OPTIONAL
    ) {
        parent::__construct(
            $context,
            $registry,
            $extensionFactory,
            $customAttributeFactory,
            $paymentData,
            $scopeConfig,
            $logger,
            $resource,
            $resourceCollection,
            $data,
            $directory
        );
        $this->_refund = $refund;
        $this->_transport = $transport;
        $this->_momoOrderFactory = $momoOrderFactory;
        $this->_config = $config;
    }

13.Show Refund in Invoice

WHEN ORDER SUCCESS, WE MUST SAVE TRANSACTION.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
$payment = $order->getPayment();
			$payment->setTransactionId(<transactionId>)
			            ->setCurrencyCode($order->getBaseCurrencyCode())
                        ->registerCaptureNotification(<amount>);




OR OR OR OR OR SURE WAY

$orderIncrementId = $this->_checkoutSession->getLastRealOrderId();
                    $order = $this->_orderFactory->create();
                    $order->loadByIncrementId($orderIncrementId);
                    $payment = $order->getPayment();
                    $payment->setTransactionId($dataResponse['out_trade_no'])
                                ->setCurrencyCode($order->getBaseCurrencyCode())
                                ->registerCaptureNotification($dataResponse['total_fee']);
                    if (!empty($dataResponse)) {
                        $payment->setAdditionalData(serialize($dataResponse));
                    }
                    $payment->save();
                    $order->save();
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
ADD BELOW CODE INTO CLASS PAYMENT
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
 	protected $_canAuthorize                = false;
    protected $_canCapture                  = false;
    protected $_canCapturePartial           = false;
    protected $_canCaptureOnce              = false;
    protected $_canRefund                   = true;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

14.Working with Order and Payment

1. Get Payment / Order

$payment = $order->getPayment();

$order = $payment->get0rder();

2. Get order

\Magento\Sales\Model\OrderFactory $orderFactory;

$order = $orderFactory->create->load(<entity_id>);

3. Save transaction

$payment = $order->getPayment();
$payment->setTransactionId(<transaction Id>)
		->setCurrencyCode($order->getBaseCurrencyCode())
        ->registerCaptureNotification(<amount>);

4. Cancel Order

$order->getPayment()->cancel();
$order->addStatusHistoryComment(<MOMO Queue changes from pending to canceled>);
$order->registerCancellation(<Cancel from MOMO with Error Code {$error}>);
$order->save();	

5. Delete a record

		$model = <modelFactory>->create();
        $model->load(<id>);
        $model->delete();

6. Save a record

		$model = <modelFactory>->create();
        $model->setData(<array>);
        $model->save();

7. Update a random field record

	$order->setState("processing");

15.Travelling to find Controller XML

FLOW 

1. Use template pathhint find Block

2. In Block find Module

3. In Module find Controller base on URL /frontname/controller/action 
	- Special case : /frontname = /frontname/index/index

	EXAMPLE caomoi.local/checkout/
4. XML : checkout_index_index.xml

Using Plugin

Using Preference

17.PHP function

1. declare(strict_types = 1) 
=> Example function Float(1, '2') return Sum two params 
=> When we use STRICT. inside function Float. 
1 int -> 1.0 float
'2' string -> 2.0 float 
=> result is 3.0.

18.Get data of Order use Qoute on JS

- - - - - - - - - - - - - - - - - - - - - - - - - - - - 
view/frontend/web/js/view/payment/method-renderer.js  |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - 
define(
    [
        'uiComponent',
        'Magento_Checkout/js/model/payment/renderer-list',
        'Magento_Checkout/js/model/quote',	<=========[[
    ],
    function (
        Component,
        rendererList,
        quote, <=========[[
    ) {

        'use strict';
        const min = 10000;
        const max = 20000000;
        var amount = quote.totals().grand_total;	<=========[[

        if(amount == null) {

        }

        else if(amount < min || amount > max) {

        } 
        else {
            rendererList.push(
                {
                    type: 'netpowermomo',
                    component: 'Netpower_Momo/js/view/payment/method-renderer/netpowermomo'
                }
            );
        }
        
        return Component.extend({});
    }
);

19.Di.xml dependency injection

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
	<preference for="<path_Interface>" type="<path_Class>" />
</config>

20.Add Payment information into admin order

1. On payment model : add [ protected $_infoBlockType = \Netpower\Momo\Block\Payment\Info::class; ]

2. Create Block file. 
<?php

namespace Netpower\Momo\Block\Payment;

use Netpower\Momo\Model\MomoOrderFactory;


class Info extends \Magento\Payment\Block\Info 
{
    /**
     * @var Netpower\Momo\Model\MomoOrderFactory
     */
    protected $_momoInfor;

    public function __construct(
        \Magento\Backend\Block\Template\Context $context, 
        MomoOrderFactory $momoInfor,
        array $data = []
    )
    {
        parent::__construct($context, $data);
        $this->_momoInfor = $momoInfor;
    }

     /**
     * Prepare Momo-specific payment information
     *
     * @param \Magento\Framework\DataObject|array|null $transport
     * @return \Magento\Framework\DataObject
     */
    protected function _prepareSpecificInformation($transport = null) <=========[[ Will render infor in admin order detail and checkout on storefront
    {

    	if (null !== $this->_paymentSpecificInformation) {
            return $this->_paymentSpecificInformation;
        }
        $transport = parent::_prepareSpecificInformation($transport);

        $data = [];

        $payment = $this->getInfo();     <========[[ 

        if($payment == null) {

        } else {
            $order = $payment->getOrder();	<===========[[

            $grandTotal = $order->getData('grand_total');
            $currency = $order->getData('store_currency_code');
            $orderId = $order->getData('entity_id');

            $orderMoMos = $this->_momoInfor->create()->getCollection()->getData();

            $orderMomoss = [];
            foreach($orderMoMos as $orderMoMo) {
                if($orderMoMo['order_id'] == $orderId) {
                    $orderMomoss = $orderMoMo; 
                    break;
                }
            }
  
            $momoId = $payType = $tranId = null;

            if($orderMomoss == []) {

            } else {
                $momoId = $orderMomoss['momo_id']; // $momoId = $requestId = $orderId
                $payType = $orderMomoss['pay_type'];
                $tranId = $orderMomoss['transaction_id'];

                $data[(string)__('Total')] =  (int)$grandTotal . ' ' .$currency;
                $data[(string)__('Request Momo Id')] = $momoId;
                $data[(string)__('Transaction Id')] = $tranId;
                $data[(string)__('Pay type')] =  $payType . ' ' .'<p> pla pla </p>' ;
                $data[(string)__('Order Momo Id')] = $momoId;
            }
        }
        $transport =  $transport->setData(array_merge($data, $transport->getData()));
       
        return $transport;
    }
}

21.Clear all discount price

- Check table eav-attribute 
*** NOTE : Backup database before doing task

|--- [1] Finding 'special-price' on attribute_code column to find attribute_id

|--- [2] Go to catalog_product_entity_decimal find attribute_id on step [1] to finding entity_id

|--- [3] Check it on frontend, admin and compare with database 
NOTE : Using entity_id go to catalog_product_entity finding SKU. Using SKU to finding Product on frontend and admin.

|--- [4] Delete all special-price in catalog_product_entity_decimal with attribute_id in step [2]

- As step to find special price. Finding from date and end date of special price attribute_id to delete all.

*EXAMPLE IN TOTO 
DELETE FROM `catalog_product_entity_decimal` WHERE `attribute_id` = 76;

DELETE FROM `catalog_product_entity_datetime` WHERE `attribute_id` = 77;

DELETE FROM `catalog_product_entity_datetime` WHERE `attribute_id` = 78;

22.Add new products using tools

- Format file csv from xsls file. 
|--- [1] Create excel file online on google drive

|--- [2] Using =ArrayFormula(""""&'Sheet name'!range&"""") 
Example : =ArrayFormula(""""&'New Product VN'!A1:E7&"""")

|--- [3] Download file formatted and open with Editor to fix """ => "

|--- [4] Go to Admin -> System -> Import/Export -> Dataflow - Profiles -> Import All Products -> Upload File -> Save.
To upload file for the tool
 
|--- [5] On production ToTo has a tool is Magmi. With path [https://vn.toto.com/tools/massimport888/web/magmi.php]

Tools using add 
--- Default : Product details, Promotion...
--- Categories : Add Raw Categories 
--- Images : Add Image for products 

How to use : 
--- Choose Type of Profile (Default, Categories or Images)
--- Select file uploaded 
--- Save Profile and Run

TO IMPORT ATTACHMENT (File pdf, dwg ...) : USING EXTENSION NETPOWER. 
--- Catalog -> Manage Attachments -> import Csv 
NOTE : Upload file with format csv : "sku","file" 
and format name of file is file.csv


*NOTE : 
-Remember upload Attachments and Images before import csv

- Import Product : Run Dataflow - Profile
- Import Categories, Images : Using Magmi Tools
- Import Attachments : Using Admin import




*************** USE Window SCP to upload file 
--------------------- Attachments : /data/www/html/media/custom/uploaded/file
--------------------- Image products : /data/www/html/media/import

LINK INSTRUCTION DETAIL : Googe Drive

FILE EXCEL EXAMPLE : Google drive

23.Install VIPPS (1hr)

  1. php72 composer.phar require vipps/module-payment LINK INSTRUCTION

  2. Config VIPPS WIKI

NOTE : Commit : composer.json and composer.lock

24.Export Data


1. Export Product

System > Import/Export > Dataflow Profiles > Create New Profile Export Products [1]. Name of Data flow [2]. Types Import | Export ; Store [3]. File name export and Path where place file [4]. Export All fields or Only Mapping fields


2. Export Categories

Use tools of TOTO [/tools/...]

<?php

define('MAGENTO', realpath(dirname(__FILE__)));
ini_set('memory_limit', '2048M');
set_time_limit (0);
require_once MAGENTO . '/../app/Mage.php';

Mage::app();
$_productCollection = Mage::getModel('catalog/product')
                        ->getCollection()
                        ->addAttributeToSort('created_at', 'DESC')
                        ->addAttributeToSelect('*')
                        ->load();
$output = Mage::getBaseDir('media') . DS . 'sample-data' . DS . 'categories.csv';
$fp = fopen($output, 'w+');
$csvHeader = array('sku','categories');
fputcsv( $fp, $csvHeader,",");

echo "<b><h1><a href='". Mage::getBaseUrl('media')."/sample-data/categories.csv'>Download Me</a></h1></b><br/>";


echo "<table style='border-collapse:collapse;width: 1702px;table-layout: fixed;'>
                        <tr><td>sku</td>
                        <td>categories</td>
                </tr>";


foreach ($_productCollection as $_product){
    $collection1 = $_product->getCategoryCollection()
        ->addAttributeToSelect('path')
        ->addAttributeToSelect('is_active');

    foreach($collection1 as $cat1){
        $pathIds = explode('/', $cat1->getPath());
        $collection = Mage::getModel('catalog/category')->getCollection()
            ->setStoreId(Mage::app()->getStore()->getId())
            ->addAttributeToSelect('name')
            ->addAttributeToSelect('is_active')
            ->addFieldToFilter('entity_id', array('in' => $pathIds));

        $pahtByName = '';
        foreach($collection as $cat){
                if ($cat->getId() == 1 || $cat->getId() == 2) {
                        # code...
                        continue;
                   }
            $pahtByName .= '/' . $cat->getName();
        }
        $pathName = substr($pahtByName, 1);
         fputcsv($fp, array($_product->getSku(),$pathName), ",");

         echo "<tr style='border-bottom:1px solid silver;'>
                        <td>{$_product->getSku()}</td>
                        <td>{$pathName}</td>
               </tr>";

    }
}

echo "</table>";
fclose($fp);

3. Export Attachments

Use tools of TOTO [/tools/...]

<?php
define('MAGENTO', realpath(dirname(__FILE__)));
ini_set('memory_limit', '2048M');
set_time_limit (0);
require_once MAGENTO . '/../app/Mage.php';

Mage::app();

class Show{
        static $_categories;

        function getCsvData($file){
                $csv = new Varien_File_Csv();
                $csvData = $csv->getData($file);
                $columns = array_shift($csvData);
                foreach ($csvData as $k => $v) {
                        $csvData[$k] = array_combine($columns, array_values($v));
                }

                return $csvData;
        }

        function getCategoryNames($ids){
                $names = array();
                foreach($ids as $id){
                        $category = $this->getCategoryById($id);
                        $names[]= $category->getName();
                }

                return $names;
        }

        function getCategoryById($id){
                if(!isset(self::$_categories)){
                        self::$_categories = array();
                }

                if(!isset(self::$_categories[$id])){
                        self::$_categories[$id] = Mage::getModel('catalog/category')->load($id);
                }

                return self::$_categories[$id];
        }

        function writeCsv($file , $data ){

                $csv = new Varien_File_Csv();
                $csv->saveData($file,$data);
        }

        public function getFileExtension($filename, $pos = 0) {
                return strtolower(substr($filename, strrpos($filename, '.') + $pos));
        }
        public function run(){
                $output = Mage::getBaseDir('media') . DS . 'sample-data' . DS . 'attachment.csv';

                $newData = [];
                $newData[]= ['product_ids', 'uploaded_file','status','exist','rule'];

                

                echo "<b><a href='". Mage::getBaseUrl('media')."/sample-data/attachment.csv'>Download Me</a></b><br/>";
                echo "Start<br/>";

                echo "<table style='border-collapse:collapse;width: 1702px;table-layout: fixed;'>
                        <tr><td>#</td>
                        <td>product_ids</td>
                        <td>exist</td>
                        <td>uploaded_file</td>
                        <td>rule</td>
                </tr>";

                $data = Mage::getModel('fileuploader/fileuploader')->getCollection();
                $data->addFieldToSelect('*');
                $data->getSelect()->joinLeft(
                        array('product' => 'catalog_product_entity'), 'main_table.product_ids=product.entity_id',
                        array('sku' => 'sku')
                );

                $count =0;
                foreach($data as $row){
                        $product_ids = $row->getProductIds();
                        $sku = $row->getSku();
                        $uploaded_file = $row->getUploadedFile();
                        $status = $row->getFileStatus();
                        $exist = file_exists('..'.$uploaded_file);

                        $ext = $this->getFileExtension($uploaded_file, 1); 

                        $title = 'Unknown';
                        $filename = explode('/',$uploaded_file);     

                        if(is_array($filename)){
                          $filename = $filename[count($filename)-1];
                          $filename_val = strtolower(str_replace(array('_','-'),array(''),$filename));
                        }
                        // echo "<h1>{$filename_val}</h1>";
                        // echo "<h2>{$ext}</h2>";
                        if(($ext=='dwg' || $ext=='dxf') && !strstr($filename_val,'3d')){
                          $title = 'CAD';
                        }else if($ext=='dxf' && strstr($filename_val,'3d')){
                          $title = '3D DXF';
                        }else if($ext=='pdf'){
                            if(strstr($filename_val,'tskt')) {
                                $title = 'TSKT';
                            }
                            else if(strstr($filename_val,'hdsd')) {
                                $title = 'HDSD';
                            }
                            else if(strstr($filename_val,'hdld')) {
                                $title = 'HDLD';
                            }
                        }else if($ext=='dwg' && strstr($filename_val,'3d')){
                          $title = '3D DWG';
                        }else if(in_array($ext,array('bmp','gif','jpg','jpeg','png'))){
                          $title = "IMAGE";
                        }else{
                          $title = "FILES OTHER";
                        }

                        $newData[] = [
                                'sku' => $sku,
                                'uploaded_file' => $uploaded_file,
                                'status' => $status,
                                'exist' => $exist ? "TRUE":"FALSE",
                                'rule' => $title  
                        ];

                        $color = "green";
                        echo "<tr style='border-bottom:1px solid silver;'>
                                        <td>{$count}</td>
                                        <td width='50px'  style='color:".($exist? 'green' : 'red')."'>{$sku}</td>
                                        <td width='50px' style='color:".($exist? 'green' : 'red')."'>".($exist ? 'TRUE' : 'FALSE')."</td>
                                        <td width='300px'>{$uploaded_file}</td>
                                        <td width='300px'>{$title}</td>
                                </tr>";
                        $count ++;
                }

                echo "</table>";
                echo "End<br/>";

                $this->writeCsv($output,$newData);
        }

}

$show = new Show();
$show->run();

25.getInstance

class::getInstance(); 

Using for singleton pattern. Declare new one object if it not existed before. And Using the Object is existing. (Only one object of getInstance exist and using).

26.get values of product attributes

EXAMPLE FOR GET ALL VALUES OF MANUFACTURER
<?php
namespace Netpower\Lenspower\Block\Attributes\Manufacturer;

use Magento\Framework\View\Element\Template\Context;

class Brands extends \Magento\Framework\View\Element\Template {
    public function __construct(
        Context $context,
        array $data = []
    ) {
        parent::__construct($context, $data);
    }

    public function getAllValue() {
        $products = \Magento\Framework\App\ObjectManager::getInstance();
        $manufacturers = $products->get('\Magento\Catalog\Model\Product\Attribute\Repository')->get('manufacturer')->getOptions();
        $values = [];
        foreach ($manufacturers as $manufacturersOption) {
            if ($manufacturersOption->getValue() != '') {
                $values[$manufacturersOption->getValue()] = $manufacturersOption->getLabel();
            }
        }
        return $values;
    }
}

27.Write javascript in phtml and using php variable

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

?>

<?php
$productId = $block->getSaleableItem()->getId();
/** @var \Magento\ConfigurableProduct\Pricing\Render\FinalPriceBox$block */

/** @var \Magento\Framework\Pricing\Price\PriceInterface $priceModel */
$priceModel = $block->getPriceType('regular_price');

/** @var \Magento\Framework\Pricing\Price\PriceInterface $finalPriceModel */
$finalPriceModel = $block->getPriceType('final_price');
$idSuffix = $block->getIdSuffix() ? $block->getIdSuffix() : '';
$schema = ($block->getZone() == 'item_view') ? true : false;
?>
<span class="normal-price">
    <?php
    $arguments = [
        'display_label' => __('As low as'),
        'price_id' => $block->getPriceId('product-price-' . $idSuffix),
        'price_type' => 'finalPrice',
        'include_container' => true,
        'schema' => $schema,
    ];
    /* @noEscape */ echo $block->renderAmount($finalPriceModel->getAmount(), $arguments);
    ?>
</span>

<?php if ($block->hasSpecialPrice()): ?>
    <?php
       $finalPriceSales = $finalPriceModel->getAmount()->getValue();
       $originalPriceSales = $priceModel->getAmount()->getValue();
       $salePricesRule = (100 - round(($finalPriceSales/$originalPriceSales)*100));
       echo $product_labels = '<div class="product-labels configurable price-rule js-configurable-price-rule-label-'.$productId.'" ><div class="product-label sale-label">'.'-'.$salePricesRule.'%'.'</div></div>';

   ?>
    <span class="old-price sly-old-price no-display">
        <?php /* @escapeNotVerified */ echo $block->renderAmount($priceModel->getAmount(), [
            'display_label'     => __('Regular Price'),
            'price_id'          => $block->getPriceId('old-price-' . $idSuffix),
            'price_type'        => 'oldPrice',
            'include_container' => true,
            'skip_adjustments'  => true
        ]); ?>
    </span>
<?php endif; ?>

<?php if ($block->showMinimalPrice()): ?>
    <?php if ($block->getUseLinkForAsLowAs()):?>
        <a href="<?= /* @escapeNotVerified */ $block->getSaleableItem()->getProductUrl() ?>" class="minimal-price-link">
            <?= /* @escapeNotVerified */ $block->renderAmountMinimal() ?>
        </a>
    <?php else:?>
        <span class="minimal-price-link">
            <?= /* @escapeNotVerified */ $block->renderAmountMinimal() ?>
        </span>
    <?php endif?>
<?php endif; ?>

=========================================================================================
<script type="text/javascript">
    require(['jquery'],
        function($) {
            console.log("<?php echo $productId ?>");
        })
</script>
=========================================================================================

28.Get data from table with multiple select on admin by ConfigProvider

EXAMPLE BLF with preference to Front-end 29. Add table field with add more field and multiple select on admin

app/code/Netpower/OnePageCheckout/Helper/Data.php
<?php
/**
 * Copyright 2019 Netpower. All rights reserved.
 */

namespace Netpower\OnePageCheckout\Helper;

use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\ScopeInterface;
use Magento\Checkout\Model\Session;

/**
 * Class Data
 * @package Netpower\Lenspower\Helper
 */
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
    CONST XML_SHIPPING_CUSTOM_DESCRIPTION_PATH = 'onepage_checkout/shipping/shipping_methods_custom_text';
    protected $shippingMethodsCustomDescription = [];

    /**
     * @param null $storeId
     * @return array
     */
    public function getShippingMethodsCustomDescriptionValues($storeId = null)
    {
        if (!$this->shippingMethodsCustomDescription) {
            $configs = $this->scopeConfig->getValue(
                self::XML_SHIPPING_CUSTOM_DESCRIPTION_PATH,
                ScopeInterface::SCOPE_STORE,
                $storeId
            );

            if (!$configs) {
                return $this->shippingMethodsCustomDescription;
            }

            $configs = json_decode($configs, true);
            $args = [];
            foreach ($configs as $field) {
                $args[] = [
                    'shipping_id' => $field['shipping_id'],
                    'custom_description' => $field['custom_description'],
                ];
            }

            $this->shippingMethodsCustomDescription = $args;
        }

        return $this->shippingMethodsCustomDescription;
    }
}

app/code/Netpower/OnePageCheckout/Model/Checkout/OnepageConfigProvider.php
<?php
/**
 * Copyright 2019 Netpower. All rights reserved.
 */

namespace Netpower\OnePageCheckout\Model\Checkout;

use Magento\Checkout\Model\ConfigProviderInterface;
use Netpower\OnePageCheckout\Helper\Data;
use Magento\Framework\UrlInterface;

/**
 * Class OnepageConfigProvider
 * @package Netpower\OnePageCheckout\Model\Checkout
 */
class OnepageConfigProvider implements ConfigProviderInterface
{
    /**
     * Url Builder
     *
     * @var UrlInterface
     */
    protected $urlBuilder;

    /**
     * @var Data
     */
    protected $dataHelper;

    /**
     * KcoConfigProvider constructor.
     * @param UrlInterface $urlBuilder
     */
    public function __construct(
        UrlInterface $urlBuilder,
        Data $dataHelper
    )
    {
        $this->urlBuilder = $urlBuilder;
        $this->dataHelper = $dataHelper;
    }

    /**
     * Get JS config
     *
     * @return array
     * @throws \Klarna\KcoCore\Exception
     * @throws \Magento\Framework\Exception\NoSuchEntityException
     */
    public function getConfig()
    {
        return [
            'onepage' => [
                'methodUrl' => $this->getUrl('checkout/onepage/saveShippingMethod')
            ],
            'shipping' => [
                'shippingMethodsCustomDescription' => $this->dataHelper->getShippingMethodsCustomDescriptionValues()
            ]
        ];
    }

    /**
     * Generate url by route and parameters
     *
     * @param string $route
     * @param array $params
     * @return string
     */
    private function getUrl($route = '', array $params = [])
    {
        return $this->urlBuilder->getUrl($route, $params);
    }
}

window.checkoutConfig : on console to test

29.Get value product attribute select box of current product

<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$product = $objectManager->get('Magento\Framework\Registry')->registry('current_product');
$attributeCode = "delivery_time";
$value = $product->getResource()->getAttribute($attributeCode)->getFrontend()->getValue($product);

?>
<div class="delivery-time-wrapper">
<p class="delivery-time"><?= __($value); ?></p>
</div>

Footer

⚠️ **GitHub.com Fallback** ⚠️