Admin Site - letronghieu4897/magento GitHub Wiki
- 1.Create new menu
- 2.Create Grid on admin
-
3.Create new field
- 3.1. Front-end : Show field
- 3.2. Back-end : source data for field
-
4.Create Config for Cron Job
- 4.1. Create Cron Group
- 4.2. Load Extention for managing CRON JOB
- 5.Remove Extension
- 6.Add Extension
- 7.Extension CustomerLock
- 8.Allow PDF on WYSIWYG
- 9.Add categories
- 10.Flow complete Order
- 11.Add Block into Page content on admin
- 12.Change password admin
- app/code/[Vendor]/[Extention]/etc/adminhtml/menu.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="Netpower_Ghn::ghn_order"
title="GHN Orders"
module="Magento_Backend"
sortOrder="5"
action="menuitem/index/index"
//parent="Magento_Sales::sales"
resource="Magento_Backend::content"
/>
</menu>
</config>
- ../vendor/magento/module-sales/etc/adminhtml/menu.xml
[1] System (Magento_Backend::system)
[2] Dashboard (Magento_Backend::dashboard)
[3] System (Magento_Backend::system)
[4] Marketing (Magento_Backend::marketing)
[5] Content (Magento_Backend::content)
[6] Stores (Magento_Backend::stores)
[7] Products (Magento_Catalog::catalog)
[8] (Magento_Backend::system_currency)
[9] Customers (Magento_Customer::customer)
[10] Find Partners & Extensions (Magento_Marketplace::partners)
[11] Reports (Magento_Reports::report)
[12] Sales (Magento_Sales::sales)
[13] UMC (Umc_Base::umc)
()] 1
Use [Magento_Backend::system] as parent? (Y/N) (N)] N
Select Parent Menu:
[1] Report (Magento_Backend::system_report)
[2] Tools (Magento_Backend::system_tools)
[3] Data Transfer (Magento_Backend::system_convert)
[4] Other Settings (Magento_Backend::system_other_settings)
[5] Extensions (Magento_Integration::system_extensions)
[6] Permissions (Magento_User::system_acl)
$ TREE
. _______________________________________________________________________
├── etc
│ └── di.xml
├── view
│ └── adminhtml
| └── layout
| └── ghn_ghn_index.xml
├── Controller
| └── Adminhtml
| └── Ghn
| └── Index.php
├── Block
│ └── Adminhtml
│ └── Order.php
│
├── Model
| ├── GhnOrder.php
| └── ResourceModel
| ├── GhnOrder.php
| └── GhnOrder
| └── Collection.php
|
. ________________________________________________________________________
- \app\code[Vendor][Extention]\etc\di.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="netpower_ghn_post_listing_data_source" xsi:type="string">Netpower\Ghn\Model\ResourceModel\GhnOrder\Collection</item>
</argument>
</arguments>
</type>
<virtualType name="Netpower\Ghn\Model\ResourceModel\Post\Grid\Collection" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
<arguments>
<argument name="mainTable" xsi:type="string">netpower_ghn_ghn</argument>
<argument name="resourceModel" xsi:type="string">Netpower\Ghn\Model\ResourceModel\GhnOrder</argument>
</arguments>
</virtualType>
</config>
- \app\code[Vendor][Extention]\view\adminhtml\layout\ghn_ghn_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="styles"/>
<body>
<referenceContainer name="content">
<block class="Netpower\Ghn\Block\Adminhtml\Order" name="ghn_grid">
<block class="Magento\Backend\Block\Widget\Grid" name="ghn_grid.grid" as="grid">
<arguments>
<argument name="id" xsi:type="string">ghn_order_id</argument>
<argument name="dataSource" xsi:type="object">Netpower\Ghn\Model\ResourceModel\GhnOrder\Collection</argument>
<argument name="default_sort" xsi:type="string">id</argument>
<argument name="default_dir" xsi:type="string">ASC</argument>
<argument name="save_parameters_in_session" xsi:type="string">1</argument>
</arguments>
<block class="Magento\Backend\Block\Widget\Grid\ColumnSet" name="ghn_grid.grid.columnSet" as="grid.columnSet">
<arguments>
<argument name="rowUrl" xsi:type="array">
<item name="path" xsi:type="string">*/*/edit</item>
</argument>
</arguments>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="ghn_order_id">
<arguments>
<argument name="header" xsi:type="string" translate="true">ID GHN</argument>
<argument name="index" xsi:type="string">ghn_order_id</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="status">
<arguments>
<argument name="header" xsi:type="string" translate="true">Status</argument>
<argument name="index" xsi:type="string">status</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="shipping_address">
<arguments>
<argument name="header" xsi:type="string" translate="true">Shipping Address</argument>
<argument name="index" xsi:type="string">shipping_address</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="service_name">
<arguments>
<argument name="header" xsi:type="string" translate="true">Service Name</argument>
<argument name="index" xsi:type="string">service_name</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="service_cost">
<arguments>
<argument name="header" xsi:type="string" translate="true">Service Cost</argument>
<argument name="index" xsi:type="string">service_cost</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="order_code">
<arguments>
<argument name="header" xsi:type="string" translate="true">Order Code</argument>
<argument name="index" xsi:type="string">order_code</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="shipping_order_id">
<arguments>
<argument name="header" xsi:type="string" translate="true">Shipping Order ID</argument>
<argument name="index" xsi:type="string">shipping_order_id</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
<block class="Magento\Backend\Block\Widget\Grid\Column" as="order_id">
<arguments>
<argument name="header" xsi:type="string" translate="true">Order ID</argument>
<argument name="index" xsi:type="string">order_id</argument>
<argument name="type" xsi:type="string">text</argument>
<argument name="column_css_class" xsi:type="string">col-id</argument>
<argument name="header_css_class" xsi:type="string">col-id</argument>
</arguments>
</block>
</block>
</block>
</block>
</referenceContainer>
</body>
</page>
- \app\code[Vendor][Extention]\Controller\Adminhtml\Ghn\Index.php
<?php
namespace Netpower\Ghn\Controller\Adminhtml\Ghn;
class Index extends \Magento\Backend\App\Action
{
protected $resultPageFactory = false;
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
)
{
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->prepend((__('GHN Order')));
return $resultPage;
}
}
- \app\code[Vendor][Extention]\Block\Adminhtml\Order.php
<?php
namespace Netpower\Ghn\Block\Adminhtml;
class Order extends \Magento\Backend\Block\Widget\Grid\Container
{
protected function _construct()
{
$this->_controller = 'adminhtml_order';
$this->_blockGroup = 'Netpower_Ghn';
$this->_headerText = __('GHN Order');
$this->_addButtonLabel = __('Create New Order');
parent::_construct();
}
}
- \app\code[Vendor][Extention]\Model\GhnOrder.php [V [3]]
$ NEW FIELD ON ADMIN and set data
. _____________________________________________________________________________
├── adminhtml
│ └── system.xml : Create new field on admin
├── Model
│ └── Config
| └── Source
| └── source.php : Set data for field (Option)
. _____________________________________________________________________________
- \app\code[Vendor][Extention]\etc\adminhtml\system.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="carriers" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="giaohangnhanh" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
<label>GHN</label>
<field id="token_ghn" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Token</label>
</field>
<field id="active" translate="label" type="select" sortOrder="3" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="name" translate="label" type="text" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Method Name</label>
</field>
<field id="price" translate="label" type="text" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Price</label>
<validate>validate-number validate-zero-or-greater</validate>
</field>
<field id="handling_type" translate="label" type="select" sortOrder="7" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Calculate Handling Fee</label>
<source_model>Magento\Shipping\Model\Source\HandlingType</source_model>
</field>
<field id="handling_fee" translate="label" type="text" sortOrder="8" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Handling Fee</label>
<validate>validate-number validate-zero-or-greater</validate>
</field>
<field id="sort_order" translate="label" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Sort Order</label>
</field>
<field id="title" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Title</label>
</field>
<field id="sallowspecific" translate="label" type="select" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Ship to Applicable Countries</label>
<frontend_class>shipping-applicable-country</frontend_class>
<source_model>Magento\Shipping\Model\Config\Source\Allspecificcountries</source_model>
</field>
<field id="specificcountry" translate="label" type="multiselect" sortOrder="91" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Ship to Specific Countries</label>
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
<can_be_empty>1</can_be_empty>
</field>
<field id="showmethod" translate="label" type="select" sortOrder="92" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Show Method if Not Applicable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="specificerrmsg" translate="label" type="textarea" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Displayed Error Message</label>
</field>
<field id="fromdistrictid" translate="label" type="select" sortOrder="101" showInDefault="1443" showInWebsite="1443" showInStore="1443">
<label>Place of Warehouse</label>
<source_model>Netpower\Ghn\Model\Config\Source\WareHouseGhn</source_model>
</field>
<field id="sync_district" translate="label comment tooltip" type="button" sortOrder="120" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Synchronize Province - District </label>
<frontend_model>Netpower\Ghn\Block\System\Config\Button</frontend_model>
</field>
</group>
</section>
</system>
</config>
Use it : <source_model>Netpower\Ghn\Model\Config\Source\[name]</source_model>
- \app\code[Vendor][Extention]\Model\Config\Source[name].php
<?php
namespace Netpower\Ghn\Model\Config\Source;
use Netpower\Ghn\Helper\GhnApi;
use Netpower\Ghn\Services\Config;
class [name] implements \Magento\Framework\Option\ArrayInterface
{
public function __construct() {
}
/**
* Options warehouse of Ghn
*
* @return array
*/
public function toOptionArray()
{
$result = array();
$result[] = [
'value' => 100,
'label' => "One Hundred"
];
}
return $result;
}
}
Data will be stored in table core_config_data
$ CRON JOB CONFIG
. _______________________________________________________________________
├── etc
│ ├── crontab.xml : Define Job and Group for Cron
| ├── cron_groups.xml : Create new Cron group
| ├── config.xml : Set default value
| └── adminhtml
| └── system.xml : Show config admin
├── Cron
│ └── FileName.php : Execute logic
├── Model
| └── Config
| └── Backend
| └── Cron.php : Store Database
. ________________________________________________________________________
- \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="ghn">
<job instance="Netpower\Ghn\Cron\SyncOrder" method="execute" name="netpower_ghn_cron">
<config_path>crontab/[ID CRON GROUP]/jobs/[NAME OF JOB]/schedule/cron_expr</config_path>
</job>
</group>
</config>
\app\code[Vendor][Extention]\etc\config.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<crontab>
<ghn>
<jobs>
<netpower_ghn_cron>
<schedule>
<cron_expr><![CDATA[0 1 * * *]]></cron_expr>
</schedule>
</netpower_ghn_cron>
</jobs>
</ghn>
</crontab>
</default>
</config>
- \app\code[Vendor][Extention]\etc\system.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="carriers" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
<group id="giaohangnhanh" translate="label" type="text" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
<label>GHN</label>
<field id="sync_district_cron" type="text" translate="label comment tooltip" sortOrder="10" showInDefault="1">
<label>Schedule Update Status GHN</label>
<validate>required-entry</validate>
<attribute type="cron"><![CDATA[netpower_ghn_cron]]></attribute>
<attribute type="group"><![CDATA[ghn]]></attribute>
<backend_model>Netpower\Ghn\Model\Config\Backend\Cron</backend_model>
<comment>
<![CDATA[For instance 0 1 * * * !]]>
</comment>
</field>
</group>
</section>
</system>
</config>
- app/code/[Vendor]/[Extention]/etc/cron_groups.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/cron_groups.xsd">
<group id="ghn">
<schedule_generate_every>2</schedule_generate_every>
<schedule_ahead_for>8</schedule_ahead_for>
<schedule_lifetime>4</schedule_lifetime>
<history_cleanup_every>10</history_cleanup_every>
<history_success_lifetime>120</history_success_lifetime>
<history_failure_lifetime>1200</history_failure_lifetime>
<use_separate_process>2</use_separate_process>
</group>
</config>
$ composer require ethanyehuda/magento2-cronjobmanager
To save data into database in core_config_data table
<?php
namespace Netpower\NERPIs\Model\Config\Backend;
class Cron extends \Magento\Framework\App\Config\Value
{
/**
* Cron string path
*/
const CRON_STRING_PATH = 'crontab/%s/jobs/%s/schedule/cron_expr';
/**
* @var \Magento\Framework\App\Config\ValueFactory
*/
protected $_configValueFactory;
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
* @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param string $runModelPath
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Framework\App\Config\ValueFactory $configValueFactory,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
$runModelPath = '',
array $data = []
) {
$this->_configValueFactory = $configValueFactory;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
public function beforeSave()
{
$label = $this->getData('field_config/label'); //Get Text between <label> TEXT </label>
$cronValue = $this->getValue();
$messageError = $this->validateCron($cronValue);
if ($messageError) {
throw new \Magento\Framework\Exception\ValidatorException($messageError);
}
parent::beforeSave();
}
protected function validateCron($expr)
{
$error = "";
$e = preg_split('#\s+#', $expr, null, PREG_SPLIT_NO_EMPTY);
if (sizeof($e)<5 || sizeof($e)>6) {
$error = __('Invalid cron expression: '. $expr);
}
return $error;
}
/**
* {@inheritdoc}
*
* @return $this
* @throws \Exception
*/
public function afterSave()
{
$cronName = $this->getData('field_config/cron'); //Get Text between <attribute type="N"> TEXT </attribute> with Type cron
$cronGroup = $this->getData('field_config/group');
$cronValue = $this->getValue();
$cronPath = sprintf(self::CRON_STRING_PATH, $cronGroup, $cronName);
try {
$this->_configValueFactory->create()->load(
$cronPath,
'path'
)->setValue(
$cronValue
)->setPath(
$cronPath
)->save();
} catch (\Exception $e) {
throw new \Exception(__('We can\'t save the cron expression.'));
}
return parent::afterSave();
}
}
$ php bin/magento module:status
$ php bin/magento module:disable <ExtensionProvider_ExtensionName> --clear-static-content
$ php bin/magento setup:upgrade
$ cd app/code/<ExtensionProvider>/
$ rm -rf <ExtensionName>
WAY 1 : COMPOSER
$ php composer.phar <name-extention> : Finding name-extention
WAY 2 : DOWNLOAD FOLDER
if : folder having structure -> Copy paste.
else if : folder not having structure
- Check file registration.php -> create folder
- EXAMPLE : Magenstore_Bannerslider -> Folder : Magenstore > Bannerslider
- Because when file run : Magenstore_Bannerslider -> Magenstore/Bannerslider
registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Magestore_Bannerslider',
__DIR__
);
- COPY ALL FOLDER INTO OTHER PROJECT
+ FROM Tfjelland
$ cp -R folder parent_folder
. _______________________________________________________________________
├── app
│ ├── code
| │ ├── Netpower
| │ │ ├── CustomerLock
| | | | ├── etc
| | | | | ├── adminhtml
| | | | | | └── system.xml
| | | | | ├── frontend
| | | | | | └── events.xml
| | | | | └── email_template.xml
| | | | |
| | | | ├── observer
| | | | | └── Customer
| | | | | └── CustomerRegisterSuccess.php
| | | | |
| | | | └── view
| | | | └── frontend
| | | | ├── layout
| | | | | └── customer_email_customer_information.xml
| | | | ├── template
| | | | | └── email
| | | | | └── Customer
| | | | | └── items.phtml
| | | | └── email
| | | | └── adminotify.html
| | | |
| │ │ └── Base
| | |
| | └── MagePsycho
| |
| └── design
| └── adminhtml
| └── Netpower
. ________________________________________________________________________
! COPY FROM Tfjelland and fix.
1. Dump Database backup on staging
2. app/code/Netpower/NERPIs/Controller/Test/Task.php (Check path controller) : To delete Category
- Example : Tfjelland.example/napi/test/task
3. Convert xlsx to csv
4. Convert csv to json
+ 5. Go to database : Table is netpower_nerpis_task
6. Column : Serialize_data
7. Copy Json to Serialize_data column
+ 8. Go to Admin > NERPIS > Task Watch
9. Go to Catalog > Categories to check results.
Task type : erp/product/task_category_import
Status : new
[
{
"categoryId":"14827",
"parentId":"11865",
"erpId":"14827",
"name":"Parafinlamper, -lykter m\/tilbe",
"companyName":null,
"description":"Fjelland Handel",
"active":true,
"created":"2019-01-15T14:33:45",
"attributes":null
}
]
1. After Place Order and Order status is Processing
2. Go to Order detail > Ship > Submit Shipment
3. > Invoice : Submit Invoice
4. In Left Side choose Invoice > Credit Memo > Refund Offline/Refund
An Example
{{block class="Netpower\Lenspower\Block\Attributes\Manufacturer\Brands" name="attributes_manufacturer_brands" template="Netpower_Lenspower::attributes/brands.phtml"}}
UPDATE admin_user SET password = CONCAT(SHA2('xxxxxxxzW7MCNHISmT2', 256),':xxxxxxx:1') WHERE username = 'netpower';
xxxxxxx : is key on app > etc > env.php
zW7MCNHISmT2 : New password