sync code

This commit is contained in:
Kai Ton 2024-05-17 08:26:28 +07:00
parent 7ef2bef4db
commit d8e59641f9
748 changed files with 22162 additions and 2660 deletions

2
.env
View File

@ -1,5 +1,5 @@
# NETWORK # NETWORK
APP_PORT=81 APP_PORT=8000
APP_URL=http://apac.host:${APP_PORT} APP_URL=http://apac.host:${APP_PORT}
# MYSQL # MYSQL

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
bin/magento cache:clean bin/magento cache:clean
bin/magento cache:flush bin/magento cache:flush

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
source "$PWD/.env" source "$PWD/.env"

6
.sh/refresh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
bin/magento setup:upgrade
bin/magento setup:static-content:deploy -f
bin/magento cache:flush
chmod 777 -R generated/ var/

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/sh
source "$PWD/.env" source "$PWD/.env"

View File

@ -0,0 +1,11 @@
<?php
namespace IpSupply\AssetRecovery\Block;
class Form extends \Magento\Framework\View\Element\Template
{
protected function _prepareLayout()
{
return parent::_prepareLayout();
}
}

View File

@ -0,0 +1,105 @@
<?php
namespace IpSupply\AssetRecovery\Controller\Index;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Framework\Escaper;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Controller\ResultFactory;
class Index extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
protected $_messageManager;
protected $resultFactory;
protected $inlineTranslation;
protected $escaper;
protected $transportBuilder;
protected $logger;
public function __construct(
Context $context,
PageFactory $pageFactory,
\Magento\Framework\Message\ManagerInterface $messageManager,
StateInterface $inlineTranslation,
Escaper $escaper,
TransportBuilder $transportBuilder,
\Magento\Framework\App\Helper\Context $helperContext
)
{
$this->pageFactory = $pageFactory;
$this->messageManager = $messageManager;
$this->resultFactory = $context->getResultFactory();
$this->inlineTranslation = $inlineTranslation;
$this->escaper = $escaper;
$this->transportBuilder = $transportBuilder;
$this->logger = $helperContext->getLogger();
parent::__construct($context);
}
public function execute()
{
$page = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$data = $this->getRequest()->getPostValue();
if (!empty($data)) {
if (!array_key_exists("name", $data)) {
$this->messageManager->addError(__("The field name is invalid"));
} else if (!array_key_exists("company_name", $data)) {
$this->messageManager->addError(__("The field company name is invalid"));
} else if (!array_key_exists("email", $data)) {
$this->messageManager->addError(__("The field email is invalid"));
} else if (!array_key_exists("phone", $data)) {
$this->messageManager->addError(__("The field phone is invalid"));
} else if (!array_key_exists("date", $data)) {
$this->messageManager->addError(__("The field date is invalid"));
} else if (!array_key_exists("items", $data)) {
$this->messageManager->addError(__("The field items is invalid"));
}else {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$scopeConfig = $objectManager->create('\Magento\Framework\App\Config\ScopeConfigInterface');
$email_contact = $scopeConfig->getValue('trans_email/ident_general/email',\Magento\Store\Model\ScopeInterface::SCOPE_STORE);
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
try {
$this->inlineTranslation->suspend();
$sender = [
'name' => $this->escaper->escapeHtml($data["name"]),
'email' => $this->escaper->escapeHtml($data["email"]),
];
$transport = $this->transportBuilder
->setTemplateIdentifier('email_asset_recovery_template')
->setTemplateOptions(
[
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
]
)
->setTemplateVars([
'name' => $data["name"],
'email' => $data["email"],
'company_name' => $data["company_name"],
'phone' => $data["phone"],
'date' => $data["date"],
'items' => nl2br($data["items"]),
])
->setFrom($sender)
->addTo($email_contact)
->getTransport();
$transport->sendMessage();
$this->inlineTranslation->resume();
$this->messageManager->addSuccess(__("Thanks you. We'll respond to you very soon."));
} catch (\Exception $e) {
$this->logger->debug($e->getMessage());
}
}
}
return $page;
}
}

View File

@ -0,0 +1,27 @@
{
"name": "ipsupply/assetrecovery",
"description": "Asset Recovery form",
"require": {
"php": "~7.1.3||~7.2.0",
"lib-libxml": "*",
"magento/framework": "102.0.*",
"magento/module-backend": "101.0.*",
"magento/module-media-storage": "100.3.*",
"magento/module-store": "101.0.*",
"magento/module-ui": "101.1.*"
},
"type": "magento2-module",
"version": "100.3.0",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"IpSupply\\AssetRecovery\\": ""
}
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
<template id="email_asset_recovery_template" label="This is email Asset Recovery" file="email_asset_recovery_template.html" type="html" module="IpSupply_AssetRecovery" area="frontend"/>
</config>

View File

@ -0,0 +1,8 @@
<?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 id="assetrecovery" frontName="asset-recovery">
<module name="IpSupply_AssetRecovery"/>
</route>
</router>
</config>

View File

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="IpSupply_AssetRecovery" setup_version="1.0.0">
</module>
</config>

View File

@ -0,0 +1,7 @@
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'IpSupply_AssetRecovery',
__DIR__
);

View File

@ -0,0 +1,32 @@
<!--@subject {{trans "Asset recovery"}} @-->
{{template config_path="design/email/header_template"}}
<table>
<tr>
<td>Name : </td>
<td>{{var name}}</td>
</tr>
<tr>
<td>Email : </td>
<td>{{var email}}</td>
</tr>
<tr>
<td>Company : </td>
<td>{{var company_name}}</td>
</tr>
<tr>
<td>Phone : </td>
<td>{{var phone}}</td>
</tr>
<tr>
<td>Date : </td>
<td>{{var date}}</td>
</tr>
<tr>
<td>Items : </td>
<td>{{var items|raw }}</td>
</tr>
</table>
<br>
<br>
{{template config_path="design/email/footer_template"}}

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Asset Recovery</title>
</head>
<referenceBlock name="content">
<block class="IpSupply\AssetRecovery\Block\Form" name="ip_supply_asset_recovery_form" template="Form.phtml" />
</referenceBlock>
</page>

View File

@ -0,0 +1,100 @@
<div class="columns">
<div class="column main">
<div class="cart-container">
<div class="cart-summary" style="top: 0px;">
<h4>SELL YOUR EXCESS ASSET</h4>
<p>
Now theres a simple way to dispose of the excess assets that let you get the best value for your
old network. Our Asset Recovery service offers you a range of flexible solutions.
</p>
<p>
Just follow 2 simple steps:
</p>
<div>
<ul>
<li>
A Fair Market Value Assessment of your equipment.
</li>
<li>
Then choose to sell it for instant cash or trade it in as credit towards new purchases.
</li>
</ul>
</div>
</div>
<form class="form contact form-cart " action="<?php echo $this->getBaseUrl(); ?>asset-recovery"
method="POST" data-mage-init='{"validation":{}}'>
<?= $block->getBlockHtml('formkey') ?>
<fieldset class="fieldset">
<div class="field name required">
<label class="label" for="name"><span>Contact Name</span></label>
<div class="control">
<input name="name" id="name" title="Name" value="" class="input-text" type="text"
data-validate="{required:true}" aria-required="true">
</div>
</div>
<div class="field name required">
<label class="label" for="company_name"><span>Company name</span></label>
<div class="control">
<input name="company_name" id="company_name" title="Company name" value=""
class="input-text" type="text" data-validate="{required:true}" aria-required="true">
</div>
</div>
<div class="field email required">
<label class="label" for="email"><span>Email Address</span></label>
<div class="control">
<input name="email" id="email" title="Email" value="" class="input-text" type="email"
data-validate="{required:true, 'validate-email':true}" aria-required="true">
</div>
</div>
<div class="field telephone required">
<label class="label" for="telephone"><span>Mobile Number</span></label>
<div class="control">
<input name="phone" id="telephone" title="Phone Number" value="" class="input-text"
type="text" data-validate="{required:true}">
</div>
</div>
<div class="field date required">
<label class="label" for="date"><span>Date</span></label>
<legend>Please use this date format: dd/mm/yyyy.</legend>
<div class="control">
<!-- <input name="date" id="date" title="Date" value="" class="input-text"
type="text" data-validate="{required:true}"> -->
<input data-validate="{required:true,'validate-date-au' : true}" type="text" name="date" id="datepicker" value="" class="datepicker input-text">
</div>
</div>
<div class="field items required">
<label class="label" for="note"><span>Item list</span></label>
<legend>Please input follow the rule Model, Qty, Condition, Description</legend>
<div class="control">
<textarea name="items" id="items" title="items" class="input-text" cols="5" rows="5"
aria-required="true"
placeholder="WS-C3850-48U-E, 1x, USEB, face damage and can not boot"
data-validate="{required:true}"></textarea>
</div>
</div>
</fieldset>
<div class="actions-toolbar">
<div class="primary">
<button type="submit" title="Submit" class="action submit primary">
<span>Send Us</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
require(["jquery", "mage/calendar"], function($) {
$("#datepicker").datepicker({
dateFormat: 'dd/mm/yy',
changeMonth: true,
changeYear: true,
yearRange: '2010:2025',
showMonthAfterYear: false,
})
});
</script>

View File

@ -0,0 +1,40 @@
<?php
namespace IpSupply\CartToQuote\Api;
interface CartItemInterface
{
/**
* POST
* @param string[] $data
* @return string
*/
public function addItem($data);
/**
* POST
* @param string[] $data
* @return string
*/
public function updateItem($data);
/**
* POST
* @param string[] $data
* @return string
*/
public function removeItem($data);
/**
* POST
* @param string[] $data
* @return string
*/
public function clearItem($data);
/**
* get
* @return string
*/
public function getData();
}

View File

@ -0,0 +1,11 @@
<?php
namespace IpSupply\CartToQuote\Api;
interface SendMailInterface
{
/**
* POST for test api
* @param string[] $data
* @return string
*/
public function sendEmail($data);
}

View File

@ -0,0 +1,29 @@
<?php
namespace IpSupply\CartToQuote\Block\Customer\History;
class Detail extends \Magento\Framework\View\Element\Template
{
protected $carttDetailFactory;
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\IpSupply\CartToQuote\Model\CartDetailFactory $carttDetailFactory,
array $data = []
)
{
$this->carttDetailFactory = $carttDetailFactory;
parent::__construct($context, $data);
}
public function getItems($customerId)
{
$id = (int) $this->getRequest()->getParam('id');
$collection = $this->carttDetailFactory->create()->getCollection();
$data = $collection->addFieldToFilter('quote_history_id', ['eq' => $id])
->addFieldToFilter('customer_id', ['eq' => $customerId])
->setOrder('name','DESC')
->getData();
return $data;
}
}
?>

View File

@ -0,0 +1,46 @@
<?php
namespace IpSupply\CartToQuote\Block\Customer\History;
class Quote extends \Magento\Framework\View\Element\Template
{
protected $carttHistoryFactory;
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\IpSupply\CartToQuote\Model\CartHistoryFactory $carttHistoryFactory,
array $data = []
)
{
$this->carttHistoryFactory = $carttHistoryFactory;
parent::__construct($context, $data);
}
public function getCarttHistories($customerId)
{
$current_page = (int) $this->getRequest()->getParam('current_page');
if ($current_page == 0) {
$current_page = 1;
}
$size = (int) $this->getRequest()->getParam('size');
if ($size == 0) {
$size = 20;
}
$collection = $this->carttHistoryFactory->create()->getCollection();
$data = $collection->addFieldToFilter('customer_id', ['eq' => $customerId])
->setOrder('date','DESC')
->setPageSize($size)
->setCurPage($current_page)
->getData();
$collection = $this->carttHistoryFactory->create()->getCollection();
$total = $collection->addFieldToFilter('customer_id', ['eq' => $customerId])
->count();
$result = array(
"data" => $data,
"total" => $total,
"current_page" => $current_page,
"size" => $size
);
return $result;
}
}
?>

View File

@ -0,0 +1,11 @@
<?php
namespace IpSupply\CartToQuote\Block;
class Quote extends \Magento\Framework\View\Element\Template
{
protected function _prepareLayout()
{
return parent::_prepareLayout();
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace IpSupply\CartToQuote\Block;
class View extends \Magento\Framework\View\Element\Template
{
protected function _prepareLayout()
{
return parent::_prepareLayout();
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace IpSupply\CartToQuote\Controller\Cart;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Detail extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
public function __construct(Context $context, PageFactory $pageFactory)
{
$this->pageFactory = $pageFactory;
parent::__construct($context);
}
public function execute()
{
return $this->pageFactory->create();
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace IpSupply\CartToQuote\Controller\Cart;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class History extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
public function __construct(Context $context, PageFactory $pageFactory)
{
$this->pageFactory = $pageFactory;
parent::__construct($context);
}
public function execute()
{
return $this->pageFactory->create();
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace IpSupply\CartToQuote\Controller\Cart;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Index extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
public function __construct(Context $context, PageFactory $pageFactory)
{
$this->pageFactory = $pageFactory;
parent::__construct($context);
}
public function execute()
{
return $this->pageFactory->create();
}
}

View File

@ -0,0 +1,89 @@
<?php
namespace IpSupply\CartToQuote\Controller\Quote;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class AddItem extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
protected $cartItemFactory;
protected $_customerRepositoryInterface;
protected $request;
protected $customerSession;
protected $objectManager;
public function __construct(
Context $context,
PageFactory $pageFactory,
\IpSupply\CartToQuote\Model\CartItemFactory $cartItemFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface,
\Magento\Framework\Webapi\Rest\Request $request
)
{
$this->cartItemFactory = $cartItemFactory;
$this->_customerRepositoryInterface = $customerRepositoryInterface;
$this->request = $request;
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->customerSession = $this->objectManager->get(\Magento\Customer\Model\Session::class);
parent::__construct($context);
}
private function getCartItems($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$data = $collection->addFieldToFilter('customer_id', ['eq' => $customerId])
->setOrder('name','ASC')
->getData();
return $data;
}
private function isCartItem($item) {
$collection = $this->cartItemFactory->create()->getCollection();
$count = $collection->addFieldToSelect('id')
->addFieldToFilter('customer_id', ['eq' => $item["customer_id"]])
->addFieldToFilter('product_id', ['eq' => $item["product_id"]])
->count();
if ($count > 0) {
return true;
}
return false;
}
private function addCartItem($item, $customer) {
if (!$this->isCartItem($item)) {
$data = $this->cartItemFactory->create()->addData([
'email' => $customer->getEmail(),
'name' => $item["name"],
'sku' => $item["sku"],
'product_id' => $item["product_id"],
'qty' => $item["qty"],
'customer_id' => $customer->getId(),
'price' => $item["price"],
'url' => $item["url"],
'image' => $item["image"]
])->save();
return $data;
}
return null;
}
public function execute()
{
$data = json_decode(file_get_contents('php://input'), TRUE);
if($this->customerSession->isLoggedIn()) {
$customer = $this->customerSession->getCustomer();
$this->addCartItem($data, $customer);
echo json_encode($this->getCartItems($customer->getId()));
exit;
} else {
echo json_encode(array());
}
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace IpSupply\CartToQuote\Controller\Quote;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Clean extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
protected $cartItemFactory;
protected $_customerRepositoryInterface;
protected $request;
protected $customerSession;
protected $objectManager;
public function __construct(
Context $context,
PageFactory $pageFactory,
\IpSupply\CartToQuote\Model\CartItemFactory $cartItemFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface,
\Magento\Framework\Webapi\Rest\Request $request
)
{
$this->cartItemFactory = $cartItemFactory;
$this->_customerRepositoryInterface = $customerRepositoryInterface;
$this->request = $request;
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->customerSession = $this->objectManager->get(\Magento\Customer\Model\Session::class);
parent::__construct($context);
}
private function getCartItems($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$data = $collection->addFieldToFilter('customer_id', ['eq' => $customerId])
->setOrder('name','ASC')
->getData();
return $data;
}
private function clearCartItem($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$count = $collection->addFieldToSelect('id')
->addFieldToFilter('customer_id', ['eq' => $customerId])
->walk('delete');
}
public function execute()
{
if($this->customerSession->isLoggedIn()) {
$customer = $this->customerSession->getCustomer();
$this->clearCartItem($customer->getId());
echo json_encode($this->getCartItems($customer->getId()));
exit;
} else {
echo json_encode(array());
}
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace IpSupply\CartToQuote\Controller\Quote;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Data extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
protected $cartItemFactory;
protected $_customerRepositoryInterface;
protected $request;
protected $customerSession;
protected $objectManager;
public function __construct(
Context $context,
PageFactory $pageFactory,
\IpSupply\CartToQuote\Model\CartItemFactory $cartItemFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface,
\Magento\Framework\Webapi\Rest\Request $request
)
{
$this->cartItemFactory = $cartItemFactory;
$this->_customerRepositoryInterface = $customerRepositoryInterface;
$this->request = $request;
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->customerSession = $this->objectManager->get(\Magento\Customer\Model\Session::class);
parent::__construct($context);
}
private function getCartItems($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$data = $collection->addFieldToFilter('customer_id', ['eq' => $customerId])
->setOrder('name','ASC')
->getData();
return $data;
}
public function execute()
{
if($this->customerSession->isLoggedIn()) {
$customer = $this->customerSession->getCustomer();
echo json_encode($this->getCartItems($customer->getId()));
exit;
} else {
echo json_encode(array());
}
}
}

View File

@ -0,0 +1,169 @@
<?php
namespace IpSupply\CartToQuote\Controller\Request;
use Magento\Framework\Translate\Inline\StateInterface;
use Magento\Framework\Escaper;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
use Magento\Framework\Controller\ResultFactory;
class Quote extends \Magento\Framework\App\Action\Action {
protected $pageFactory;
protected $_messageManager;
protected $resultFactory;
protected $inlineTranslation;
protected $escaper;
protected $transportBuilder;
protected $logger;
protected $carttHistoryFactory;
protected $carttDetailFactory;
protected $cartItemFactory;
public function __construct(
Context $context,
PageFactory $pageFactory,
\Magento\Framework\Message\ManagerInterface $messageManager,
StateInterface $inlineTranslation,
Escaper $escaper,
TransportBuilder $transportBuilder,
\Magento\Framework\App\Helper\Context $helperContext,
\IpSupply\CartToQuote\Model\CartHistoryFactory $carttHistoryFactory,
\IpSupply\CartToQuote\Model\CartDetailFactory $carttDetailFactory,
\IpSupply\CartToQuote\Model\CartItemFactory $cartItemFactory
)
{
$this->pageFactory = $pageFactory;
$this->messageManager = $messageManager;
$this->resultFactory = $context->getResultFactory();
$this->inlineTranslation = $inlineTranslation;
$this->escaper = $escaper;
$this->transportBuilder = $transportBuilder;
$this->logger = $helperContext->getLogger();
$this->carttHistoryFactory = $carttHistoryFactory;
$this->carttDetailFactory = $carttDetailFactory;
$this->cartItemFactory = $cartItemFactory;
parent::__construct($context);
}
public function addCartHistory($itemsTotal, $customerId) {
$cartHistory = $this->carttHistoryFactory->create()->addData([
'items_total' => $itemsTotal,
'customer_id' => $customerId
])->save();
return $cartHistory->getId();
}
private function clearCartItem($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$count = $collection->addFieldToSelect('id')
->addFieldToFilter('customer_id', ['eq' => $customerId])
->walk('delete');
}
public function addCartDetail($quoteHistoryId, $items) {
foreach ($items as $item) {
$data = $this->carttDetailFactory->create()->addData([
'product_id' => $item['product_id'],
'name' => $item['name'],
'url' => $item['url'],
'image' => $item['image'],
'sku' => $item['sku'],
'qty' => $item['qty'],
'price' => $item['price'],
'customer_id' => $item['customer_id'],
'quote_history_id' => $quoteHistoryId
])->save();
}
}
public function getCartItems($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$data = $collection->addFieldToFilter('customer_id', ['eq' => $customerId])
->setOrder('name','ASC')
->getData();
return $data;
}
public function execute()
{
$page = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$block = $page->getLayout()->getBlock('ip_supply_cart_to_quote_request_quote');
$data = $this->getRequest()->getPostValue();
if (!empty($data)) {
if (!array_key_exists("name", $data)) {
$this->messageManager->addError(__("The field name is invalid"));
} else if (!array_key_exists("company_name", $data)) {
$this->messageManager->addError(__("The field company name is invalid"));
} else if (!array_key_exists("email", $data)) {
$this->messageManager->addError(__("The field email is invalid"));
} else if (!array_key_exists("phone", $data)) {
$this->messageManager->addError(__("The field phone is invalid"));
} else if (!array_key_exists("inquiry", $data)) {
$this->messageManager->addError(__("The field inquiry is invalid"));
} else if (!array_key_exists("note", $data)) {
$this->messageManager->addError(__("The field note is invalid"));
}else {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$scopeConfig = $objectManager->create('\Magento\Framework\App\Config\ScopeConfigInterface');
$email_contact = $scopeConfig->getValue('trans_email/ident_general/email',\Magento\Store\Model\ScopeInterface::SCOPE_STORE);
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
if ($customerSession->isLoggedIn()) {
$items = $this->getCartItems($customerSession->getCustomer()->getId());
if (count($items) > 0) {
$cartHistoryId = $this->addCartHistory(count($items), $customerSession->getCustomer()->getId());
if ($cartHistoryId > 0) {
$this->addCartDetail($cartHistoryId, $items);
}
}
$inquirys = array();
foreach ($items as $item) {
array_push($inquirys, $item["sku"] . " : " . $item["qty"]);
}
$data["inquiry"] = implode(".",$inquirys);
$this->clearCartItem($customerSession->getCustomer()->getId());
}
try {
$this->inlineTranslation->suspend();
$sender = [
'name' => $this->escaper->escapeHtml($data["name"]),
'email' => $this->escaper->escapeHtml($data["email"]),
];
$transport = $this->transportBuilder
->setTemplateIdentifier('email_request_quote_template')
->setTemplateOptions(
[
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'store' => \Magento\Store\Model\Store::DEFAULT_STORE_ID,
]
)
->setTemplateVars([
'name' => $data["name"],
'email' => $data["email"],
'company_name' => $data["company_name"],
'phone' => $data["phone"],
'inquiry' => str_replace(".","<br>",$data["inquiry"]),
'note' => $data["note"],
])
->setFrom($sender)
->addTo($email_contact)
->getTransport();
$transport->sendMessage();
$this->inlineTranslation->resume();
$this->messageManager->addSuccess(__("Thank you. We'll get back to you very soon."));
} catch (\Exception $e) {
$this->logger->debug($e->getMessage());
}
}
}
return $page;
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace IpSupply\CartToQuote\Model;
class CartDetail extends \Magento\Framework\Model\AbstractModel
{
protected function _construct()
{
$this->_init('IpSupply\CartToQuote\Model\ResourceModel\CartDetail');
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace IpSupply\CartToQuote\Model;
class CartHistory extends \Magento\Framework\Model\AbstractModel
{
protected function _construct()
{
$this->_init('IpSupply\CartToQuote\Model\ResourceModel\CartHistory');
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace IpSupply\CartToQuote\Model;
class CartItem extends \Magento\Framework\Model\AbstractModel
{
protected function _construct()
{
$this->_init('IpSupply\CartToQuote\Model\ResourceModel\CartItem');
}
}

View File

@ -0,0 +1,184 @@
<?php
namespace IpSupply\CartToQuote\Model;
use Magento\Framework\App\Helper\Context;
use IpSupply\CartToQuote\Api\CartItemInterface;
use Magento\Framework\ObjectManagerInterface;
class CartItemApi extends \Magento\Framework\App\Helper\AbstractHelper implements CartItemInterface
{
protected $cartItemFactory;
protected $_customerRepositoryInterface;
protected $request;
public function __construct(
Context $context,
\IpSupply\CartToQuote\Model\CartItemFactory $cartItemFactory,
\Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface,
\Magento\Framework\Webapi\Rest\Request $request
) {
$this->cartItemFactory = $cartItemFactory;
$this->_customerRepositoryInterface = $customerRepositoryInterface;
$this->request = $request;
parent::__construct($context);
}
private function getCartItems($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$data = $collection->addFieldToFilter('customer_id', ['eq' => $customerId])
->setOrder('name','ASC')
->getData();
return $data;
}
private function isCartItem($item) {
$collection = $this->cartItemFactory->create()->getCollection();
$count = $collection->addFieldToSelect('id')
->addFieldToFilter('customer_id', ['eq' => $item["customer_id"]])
->addFieldToFilter('product_id', ['eq' => $item["product_id"]])
->count();
if ($count > 0) {
return true;
}
return false;
}
private function addCartItem($item) {
if (!$this->isCartItem($item)) {
$data = $this->cartItemFactory->create()->addData([
'email' => $item["email"],
'name' => $item["name"],
'sku' => $item["sku"],
'product_id' => $item["product_id"],
'qty' => $item["qty"],
'customer_id' => $item["customer_id"],
'price' => $item["price"],
'url' => $item["url"],
'image' => $item["image"]
])->save();
return $data;
}
return null;
}
private function removeCartItem($item) {
$collection = $this->cartItemFactory->create()->getCollection();
$count = $collection->addFieldToSelect('id')
->addFieldToFilter('customer_id', ['eq' => $item["customer_id"]])
->addFieldToFilter('product_id', ['eq' => $item["product_id"]])
->walk('delete');
}
private function clearCartItem($customerId) {
$collection = $this->cartItemFactory->create()->getCollection();
$count = $collection->addFieldToSelect('id')
->addFieldToFilter('customer_id', ['eq' => $customerId])
->walk('delete');
}
private function getCurrentCustomerId($data){
$customer = $this->_customerRepositoryInterface->getById($data['customer_id']);
if ($customer) {
if ($customer->getEmail() == $data['email']){
return $customer->getId();
}
}
$customerId = $this->sessionFactory->create()->getCustomer()->getId();
return 0;
}
/**
* POST
* @param string[] $data
* @return string
*/
public function addItem($data){
$currentCustomerId = $this->getCurrentCustomerId($data);
if ($currentCustomerId == 0) {
return [];
}
$data['customer_id'] = $currentCustomerId;
if (!$this->isCartItem($data)) {
$this->addCartItem($data);
}
return $this->getCartItems($currentCustomerId);
}
/**
* POST
* @param string[] $data
* @return string
*/
public function updateItem($data){
$currentCustomerId = $this->getCurrentCustomerId($data);
if ($currentCustomerId == 0) {
return [];
}
$data['customer_id'] = $currentCustomerId;
if ($this->isCartItem($data)) {
$this->removeCartItem($data);
$this->addCartItem($data);
}
return $this->getCartItems($currentCustomerId);
}
/**
* POST
* @param string[] $data
* @return string
*/
public function removeItem($data){
$currentCustomerId = $this->getCurrentCustomerId($data);
if ($currentCustomerId == 0) {
return [];
}
$data['customer_id'] = $currentCustomerId;
$this->removeCartItem($data);
return $this->getCartItems($currentCustomerId);
}
/**
* get
* @return string
*/
public function getData(){
$par = $this->_request->getParams();
if (!array_key_exists('customer_id', $par) || !array_key_exists('email', $par)) {
return [];
}
$currentCustomerId = $this->getCurrentCustomerId($par);
if ($currentCustomerId == 0) {
return [];
}
return $this->getCartItems($currentCustomerId);
}
/**
* POST
* @param string[] $data
* @return string
*/
public function clearItem($data){
$currentCustomerId = $this->getCurrentCustomerId($data);
if ($currentCustomerId == 0) {
return [];
}
$this->clearCartItem($currentCustomerId);
return $this->getCartItems($currentCustomerId);
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace IpSupply\CartToQuote\Model\ResourceModel;
class CartDetail extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
// Table name + primary key column
$this->_init('ip_supply_cart_to_quote_detail', 'id');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace IpSupply\CartToQuote\Model\ResourceModel\CartDetail;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected function _construct()
{
// Model + Resource Model
$this->_init('IpSupply\CartToQuote\Model\CartDetail', 'IpSupply\CartToQuote\Model\ResourceModel\CartDetail');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace IpSupply\CartToQuote\Model\ResourceModel;
class CartHistory extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
// Table name + primary key column
$this->_init('ip_supply_cart_to_quote_history', 'id');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace IpSupply\CartToQuote\Model\ResourceModel\CartHistory;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected function _construct()
{
// Model + Resource Model
$this->_init('IpSupply\CartToQuote\Model\CartHistory', 'IpSupply\CartToQuote\Model\ResourceModel\CartHistory');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace IpSupply\CartToQuote\Model\ResourceModel;
class CartItem extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
protected function _construct()
{
// Table name + primary key column
$this->_init('ip_supply_cart_to_quote_item', 'id');
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace IpSupply\CartToQuote\Model\ResourceModel\CartItem;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected function _construct()
{
// Model + Resource Model
$this->_init('IpSupply\CartToQuote\Model\CartItem', 'IpSupply\CartToQuote\Model\ResourceModel\CartItem');
}
}

View File

@ -0,0 +1,165 @@
<?php
namespace IpSupply\CartToQuote\Setup;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\DB\Ddl\Table;
class InstallSchema implements \Magento\Framework\Setup\InstallSchemaInterface
{
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
$connection = $setup->getConnection();
$tableCartItem = $setup->getTable("ip_supply_cart_to_quote_item");
$tableCartHistory = $setup->getTable("ip_supply_cart_to_quote_history");
$tableCartdetail = $setup->getTable("ip_supply_cart_to_quote_detail");
if ($connection->isTableExists($tableCartItem) != true) {
$table = $connection->newTable($tableCartItem)->addColumn(
'id',
Table::TYPE_INTEGER,
null,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true]
)->addColumn(
'product_id',
Table::TYPE_INTEGER,
null,
['nullable' => false]
)->addColumn(
'email',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)
->addColumn(
'name',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'url',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'image',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'sku',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'qty',
Table::TYPE_INTEGER,
null,
['nullable' => false, 'default' => 0]
)->addColumn(
'customer_id',
Table::TYPE_INTEGER,
null,
['nullable' => false]
)->addColumn(
'price',
Table::TYPE_DECIMAL,
null,
['nullable' => false, 'default' => 0, 'scale'=> 1, 'precision'=> 13]
)
->setOption('charset', 'utf8');
$connection->createTable($table);
}
if ($connection->isTableExists($tableCartHistory) != true) {
$table = $connection->newTable($tableCartHistory)->addColumn(
'id',
Table::TYPE_INTEGER,
null,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true]
)->addColumn(
'date',
Table::TYPE_TIMESTAMP,
null,
['nullable' => false, 'default' => 'CURRENT_TIMESTAMP']
)->addColumn(
'items_total',
Table::TYPE_INTEGER,
null,
['nullable' => false]
)->addColumn(
'customer_id',
Table::TYPE_INTEGER,
null,
['nullable' => false]
)
->setOption('charset', 'utf8');
$connection->createTable($table);
}
if ($connection->isTableExists($tableCartdetail) != true) {
$table = $connection->newTable($tableCartdetail)->addColumn(
'id',
Table::TYPE_INTEGER,
null,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true]
)->addColumn(
'product_id',
Table::TYPE_INTEGER,
null,
['nullable' => false]
)
->addColumn(
'name',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'url',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'image',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'sku',
Table::TYPE_TEXT,
255,
['nullable' => false, 'default' => '']
)->addColumn(
'qty',
Table::TYPE_INTEGER,
null,
['nullable' => false, 'default' => 0]
)->addColumn(
'customer_id',
Table::TYPE_INTEGER,
null,
['nullable' => false]
)->addColumn(
'price',
Table::TYPE_DECIMAL,
null,
['nullable' => false, 'default' => 0, 'scale'=> 1, 'precision'=> 13]
)->addColumn(
'quote_history_id',
Table::TYPE_INTEGER,
null,
['nullable' => false]
)
->setOption('charset', 'utf8');
$connection->createTable($table);
}
$setup->endSetup();
}
}

View File

@ -0,0 +1,27 @@
{
"name": "ipsupply/carttoquote",
"description": "cart to quote",
"require": {
"php": "~7.1.3||~7.2.0",
"lib-libxml": "*",
"magento/framework": "102.0.*",
"magento/module-backend": "101.0.*",
"magento/module-media-storage": "100.3.*",
"magento/module-store": "101.0.*",
"magento/module-ui": "101.1.*"
},
"type": "magento2-module",
"version": "100.3.0",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"IpSupply\\CartToQuote\\": ""
}
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="IpSupply\CartToQuote\Api\CartItemInterface" type="IpSupply\CartToQuote\Model\CartItemApi"/>
</config>

View File

@ -0,0 +1,4 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
<template id="email_request_quote_template" label="This is email request quote" file="email_request_quote_template.html" type="html" module="IpSupply_CartToQuote" area="frontend"/>
</config>

View File

@ -0,0 +1,8 @@
<?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 id="carttoquote" frontName="carttoquote">
<module name="IpSupply_CartToQuote" />
</route>
</router>
</config>

View File

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="IpSupply_CartToQuote" setup_version="1.0.0">
</module>
</config>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" ?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route url="/V1/request/quote/add_item/" method="POST">
<service class="IpSupply\CartToQuote\Api\CartItemInterface" method="addItem"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/request/quote/get_data/" method="GET">
<service class="IpSupply\CartToQuote\Api\CartItemInterface" method="getData"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/request/quote/remove_item/" method="POST">
<service class="IpSupply\CartToQuote\Api\CartItemInterface" method="removeItem"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/request/quote/update_item/" method="POST">
<service class="IpSupply\CartToQuote\Api\CartItemInterface" method="updateItem"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
<route url="/V1/request/quote/clear_item/" method="POST">
<service class="IpSupply\CartToQuote\Api\CartItemInterface" method="clearItem"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>

View File

@ -0,0 +1,7 @@
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'IpSupply_CartToQuote',
__DIR__
);

View File

@ -0,0 +1,15 @@
<!--@subject {{trans "Request Quote"}} @-->
{{template config_path="design/email/header_template"}}
<h3 style="margin-top:0;margin-bottom:0px">New request quote detail</h3>
<table>
<td style="font-family:&quot;Open Sans&quot;,&quot;Helvetica Neue&quot;,Helvetica,Arial,sans-serif;vertical-align:top;background-color:#fff;padding:25px">
<p style="margin-top:0;margin-bottom:10px">Name: {{var name}}</p>
<p style="margin-top:0;margin-bottom:10px">Email: {{var email|raw}}</p>
<p style="margin-top:0;margin-bottom:10px">Company: {{var company_name}}</p>
<p style="margin-top:0;margin-bottom:10px">Phone: {{var phone}}</p>
<p style="margin-top:0;margin-bottom:10px"><b>Inquiry</b>: <b style="font-weight: normal; border: 1px solid #dfdfdf;padding: 5px 10px;">{{var inquiry|raw }}</b></p>
<p style="margin-top:0;margin-bottom:10px">Note: {{var note|raw }}</p>
</td>
</table>
{{template config_path="design/email/footer_template"}}

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="customer_account"/>
<head>
<title>
History Quotes Detail
</title>
</head>
<body>
<referenceContainer name="content">
<block class="IpSupply\CartToQuote\Block\Customer\History\Detail" name="cartToQuote.customer.history_quote.detail" template="IpSupply_CartToQuote::customer/history/detail.phtml" cacheable="false" />
</referenceContainer>
</body>
</page>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="customer_account"/>
<head>
<title>
History Quotes
</title>
</head>
<body>
<referenceContainer name="content">
<block class="IpSupply\CartToQuote\Block\Customer\History\Quote" name="cartToQuote.customer.history_quote.index" template="IpSupply_CartToQuote::customer/history/quote.phtml" cacheable="false" />
</referenceContainer>
</body>
</page>

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Cart Quotes</title>
</head>
<referenceBlock name="content">
<block class="IpSupply\CartToQuote\Block\View" name="ip_supply_cart_to_quote_detail" template="view.phtml" />
</referenceBlock>
</page>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="customer_account"/>
<head>
<title>
History Quotes
</title>
</head>
<body>
<referenceContainer name="content">
<block class="IpSupply\CartToQuote\Block\Customer\History\Quote" name="cartToQuote.customer.history_quote.index" template="IpSupply_CartToQuote::customer/history/quote.phtml" cacheable="false" />
</referenceContainer>
</body>
</page>

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<title>Organise a quote</title>
</head>
<referenceBlock name="content">
<block class="IpSupply\CartToQuote\Block\Quote" name="ip_supply_cart_to_quote_request_quote" template="quote.phtml" />
</referenceBlock>
</page>

View File

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info">
<action method="setTemplate">
<argument name="template" xsi:type="string">IpSupply_CartToQuote::product/view/form.phtml</argument>
</action>
</referenceBlock>
</body>
</page>

View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="customer_account_navigation">
<block class="Magento\Framework\View\Element\Html\Link\Current" name="customer-account-navigation-demo-link">
<arguments>
<argument name="path" xsi:type="string">carttoquote/cart/history</argument>
<argument name="label" xsi:type="string">History Quotes</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>

View File

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="top.search">
<action method="setTemplate">
<argument name="template" xsi:type="string">IpSupply_CartToQuote::form.mini.phtml</argument>
</action>
</referenceBlock>
</body>
</page>

View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="IpSupply_CartToQuote::css/cart_to_quote.css"/>
<script src="IpSupply_CartToQuote::js/toast.min.js" />
</head>
</page>

View File

@ -0,0 +1,7 @@
var config = {
map: {
'*': {
"cart_to_quote": 'IpSupply_CartToQuote/js/cart_to_quote'
}
}
};

View File

@ -0,0 +1,49 @@
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
if ($customerSession->isLoggedIn()) {
$items = $block->getItems($customerSession->getCustomer()->getId());
if (count($items) == 0 ) {
?>
<div class="message info empty"><span>You have placed no Items.</span></div>
<?php
}
else {
?>
<div class="table-wrapper orders-history">
<table class="data table table-order-items history" id="my-quote-table">
<caption class="table-caption">Orders</caption>
<thead>
<tr>
<th scope="col" class="col id">#</th>
<th scope="col" class="col id">Product Name</th>
<th scope="col" class="col date">SKU</th>
<th scope="col" class="col total">Qty</th>
</tr>
</thead>
<tbody>
<?php
foreach ($items as $item) {
?>
<tr>
<td>
<img src="<?php echo $item['image']; ?>"
style="width:100px">
</td>
<td data-th="Product Name #" class="col id"><?php echo $item['name']; ?></td>
<td data-th="SKU" class="col date"><?php echo $item['sku']; ?></td>
<td data-th="Qty" class="col shipping"><?php echo $item['qty']; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php
}
?>
<?php
}
?>

View File

@ -0,0 +1,133 @@
<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
if ($customerSession->isLoggedIn()) {
$cart = $block->getCarttHistories($customerSession->getCustomer()->getId());
if (count($cart["data"]) == 0 ) {
?>
<div class="message info empty"><span>You have placed no Items.</span></div>
<?php
}
else {
?>
<div class="table-wrapper orders-history">
<table class="data table table-order-items history" id="my-quote-table">
<caption class="table-caption">Orders</caption>
<thead>
<tr>
<th scope="col" class="col id">Id #</th>
<th scope="col" class="col date">Date</th>
<th scope="col" class="col total">Items Total</th>
<th scope="col" class="col actions">Action</th>
</tr>
</thead>
<tbody>
<?php
foreach ($cart["data"] as $item) {
?>
<tr>
<td data-th="Order #" class="col id"><?php echo $item['id'] ?></td>
<td data-th="Date" class="col date"><?php echo $item['date'] ?></td>
<td data-th="Items Total" class="col shipping"><?php echo $item['items_total'] ?></td>
<td data-th="Actions" class="col actions">
<a href="<?php echo $this->getBaseUrl() .'carttoquote/cart'; ?>/detail?id=<?php echo $item['id']; ?>"
class="action view">
<span>View</span>
</a>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
</div>
<?php
if ( $cart["total"] > count($cart["data"]) ) {
?>
<div class="pages">
<strong class="label pages-label" id="paging-label">Page</strong>
<ul class="items pages-items" aria-labelledby="paging-label">
<?php
if ($cart["current_page"] > 1) {
?>
<li class="item pages-item-previous">
<a class="action previous"
href="<?php echo $this->getBaseUrl() .'carttoquote/cart/history?size='.$cart["size"].'&current_page='.($cart["current_page"] - 1 ); ?>"
title="Previous">
<span class="label">Page</span>
<span>Previous</span>
</a>
</li>
<?php
}
?>
<?php
$totalPage = (int) ($cart["total"] / $cart["size"]);
if ( ( $cart["total"] % $cart["size"]) > 0 ) {
$totalPage = $totalPage + 1;
}
$start = $cart["current_page"] - 2;
if ($start < 1) {
$start = 1;
}
$end = $cart["current_page"] + 2;
if ($end > $totalPage) {
$end = $totalPage;
}
if ($end > $start) {
for ($i = $start; $i <= $end; $i++) {
if ($i == $cart["current_page"] || ( $totalPage == $i && $cart["current_page"] > $totalPage)) {
?>
<li class="item current">
<strong class="page">
<span class="label">You're currently reading page</span>
<span><?php echo $i; ?></span>
</strong>
</li>
<?php
}
else {
?>
<li class="item">
<a href="<?php echo $this->getBaseUrl() .'carttoquote/cart/history?size='.$cart["size"].'&current_page='.$i; ?>"
class="page">
<span class="label">Page</span>
<span><?php echo $i; ?></span>
</a>
</li>
<?php
}
}
}
if ( $totalPage > $cart["current_page"]) {
?>
<li class="item pages-item-next">
<a class="action next" href="<?php echo $this->getBaseUrl() .'carttoquote/cart/history?size='.$cart["size"].'&current_page='.($cart["current_page"] + 1 ); ?>" title="Next">
<span class="label">Page</span>
<span>Next</span>
</a>
</li>
<?php
}
?>
</ul>
</div>
<?php
}
}
?>
<?php
}
?>

View File

@ -0,0 +1,95 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// @codingStandardsIgnoreFile
?>
<?php
/** @var $block \Magento\Framework\View\Element\Template */
/** @var $helper \Magento\Search\Helper\Data */
$helper = $this->helper(\Magento\Search\Helper\Data::class);
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$request = $objectManager->get('\Magento\Framework\App\Request\Http');
if ($request->getFullActionName() == 'catalog_category_view') {
?>
<script>
require(['jquery'], function($) {
$("#maincontent").addClass("page-categories");
});
</script>
<?php
}
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
$email = "";
$customer_id = "";
if ($customerSession->isLoggedIn()) {
$email = $customerSession->getCustomer()->getEmail();
$customer_id = $customerSession->getCustomer()->getId();
}
?>
<div class="block block-search">
<div class="block block-title"><strong><?= /* @escapeNotVerified */ __('Search') ?></strong></div>
<div class="block block-content">
<form class="form minisearch" id="search_mini_form" action="<?= /* @escapeNotVerified */ $helper->getResultUrl() ?>" method="get">
<div class="field search">
<label class="label" for="search" data-role="minisearch-label">
<span><?= /* @escapeNotVerified */ __('Search') ?></span>
</label>
<div class="control">
<input id="search"
data-mage-init='{"quickSearch":{
"formSelector":"#search_mini_form",
"url":"<?= /* @escapeNotVerified */ $helper->getSuggestUrl()?>",
"destinationSelector":"#search_autocomplete"}
}'
type="text"
name="<?= /* @escapeNotVerified */ $helper->getQueryParamName() ?>"
value="<?= /* @escapeNotVerified */ $helper->getEscapedQueryText() ?>"
placeholder="<?= /* @escapeNotVerified */ __('Search entire store here...') ?>"
class="input-text"
maxlength="<?= /* @escapeNotVerified */ $helper->getMaxQueryLength() ?>"
role="combobox"
aria-haspopup="false"
aria-autocomplete="both"
autocomplete="off"/>
<div id="search_autocomplete" class="search-autocomplete"></div>
<?= $block->getChildHtml() ?>
</div>
</div>
<div class="actions">
<button type="submit"
title="<?= $block->escapeHtml(__('Search')) ?>"
class="action search">
<span><?= /* @escapeNotVerified */ __('Search') ?></span>
</button>
</div>
</form>
</div>
</div>
<script>
require(['jquery'], function($) {
$( document ).ready(function() {
if ($(".stock.unavailable span").length > 0 ) {
$(".stock.unavailable span").html("Price on request");
$(".stock.unavailable").show();
}
$( document ).ajaxComplete(function( event, xhr, settings ) {
if (settings.url.includes("mageworx_searchsuiteautocomplete/ajax/index")) {
$(".qs-option-price .normal-price .price").each(function( index ) {
$(this).html("From " + $(this).html());
});
}
});
});
});
</script>

View File

@ -0,0 +1,99 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
// @codingStandardsIgnoreFile
/**
* Product view template
*
* @var $block \Magento\Catalog\Block\Product\View
*/
?>
<?php $_helper = $this->helper('Magento\Catalog\Helper\Output'); ?>
<?php
$_product = $block->getProduct();
$configId = $_product->getTypeId();
$price = round($_product->getPrice(), 2);
if ($configId == 'configurable') {
$regularPrice = $_product->getPriceInfo()->getPrice('regular_price');
$price = $regularPrice->getMinRegularAmount();
}
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customerSession = $objectManager->create('Magento\Customer\Model\Session');
$email = "";
$customer_id = 0;
//echo $_product->getId() . '_' . $_product->getSku();
// die;
if ($customerSession->isLoggedIn()) {
// $customerSession->getCustomerId(); // get Customer Id
// $customerSession->getCustomerGroupId();
// $customerSession->getCustomer();
// $customerSession->getCustomerData();
$email = $customerSession->getCustomer()->getEmail();
$customer_id = $customerSession->getCustomer()->getId();
}
?>
<script>
//alert("<?= $_product->getId(); ?>")
console.log("id : ","<?php echo $_product->getId(); ?>");
window._product = {
product_id : "<?php echo $_product->getId(); ?>",
sku : "<?php echo $_product->getSku(); ?>",
name : "<?php echo str_replace(array('"',"'"),"",$_product->getName()); ?>",
price : <?php echo $price; ?>,
qty : 1,
email : "<?php echo $email; ?>",
customer_id : "<?php echo $customer_id; ?>",
image : "<?php echo str_replace(array( '\\'),"/",$block->getImage($block->getProduct(), 'product_base_image')->getImageUrl()) ?>",
url : "<?php echo $_product->getProductUrl(); ?>"
};
</script>
<div class="product attribute">
<!-- <button disabled="disabled" title="Add to Quote" id="product-addtocartquote-button">
<span>Add to Quote</span>
</button> -->
</div>
<div class="product-add-form">
<form data-product-sku="<?= $block->escapeHtml($_product->getSku()) ?>"
action="<?= /* @NoEscape */ $block->getSubmitUrl($_product) ?>" method="post"
id="product_addtocart_form"<?php if ($_product->getOptions()): ?> enctype="multipart/form-data"<?php endif; ?>>
<input type="hidden" name="product" value="<?= /* @escapeNotVerified */ $_product->getId() ?>" />
<input type="hidden" name="selected_configurable_option" value="" />
<input type="hidden" name="related_product" id="related-products-field" value="" />
<input type="hidden" name="item" value="<?= /* @noEscape */ $block->getRequest()->getParam('id') ?>" />
<?= $block->getBlockHtml('formkey') ?>
<?= $block->getChildHtml('form_top') ?>
<?php if (!$block->hasOptions()):?>
<?= $block->getChildHtml('product_info_form_content') ?>
<?php else:?>
<?php if ($block->getOptionsContainer() == 'container1'):?>
<?= $block->getChildChildHtml('options_container') ?>
<?php endif;?>
<?php endif; ?>
<?php if ($block->hasOptions() && $block->getOptionsContainer() == 'container2'):?>
<?= $block->getChildChildHtml('options_container') ?>
<?php endif;?>
<?= $block->getChildHtml('form_bottom') ?>
</form>
</div>
<script>
require([
'jquery',
'priceBox'
], function($){
var dataPriceBoxSelector = '[data-role=priceBox]',
dataProductIdSelector = '[data-product-id=<?= $block->escapeHtml($_product->getId()) ?>]',
priceBoxes = $(dataPriceBoxSelector + dataProductIdSelector);
priceBoxes = priceBoxes.filter(function(index, elem){
return !$(elem).find('.price-from').length;
});
priceBoxes.priceBox({'priceConfig': <?= /* @escapeNotVerified */ $block->getJsonConfig() ?>});
});
</script>

View File

@ -0,0 +1,112 @@
<div class="columns">
<div class="column main">
<div class="cart-container">
<div class="cart-summary" style="top: 0px;">
<h4>How to bulk quote processing? <?php echo $block->getData('postData'); ?></h4>
<div>
<ul>
<li>
Fill your basic information in the form (keep in mind the require fields)
</li>
<li>
Add model name and quantities to “Inquiry detail”
</li>
<li>
Review your full selection in the form
</li>
<li>
Click “Send Us”
</li>
<li>
Alternatively call us on +61 2 8061 6886, and we'll get back to you as soon as possible.
</li>
</ul>
</div>
</div>
<form class="form contact form-cart form-quote" action="<?php echo $this->getBaseUrl(); ?>carttoquote/request/quote" method="POST" data-mage-init='{"validation":{}}'>
<?= $block->getBlockHtml('formkey') ?>
<fieldset class="fieldset">
<div class="field name required">
<label class="label" for="name"><span>Name</span></label>
<div class="control">
<input name="name" id="name" title="Name" value="" class="input-text" type="text"
data-validate="{required:true}" aria-required="true">
</div>
</div>
<div class="field name required">
<label class="label" for="company_name"><span>Company name</span></label>
<div class="control">
<input name="company_name" id="company_name" title="Company name" value=""
class="input-text" type="text" data-validate="{required:true}" aria-required="true">
</div>
</div>
<div class="field email required">
<label class="label" for="email"><span>Email</span></label>
<div class="control">
<input name="email" id="email" title="Email" value="" class="input-text" type="email"
data-validate="{required:true, 'validate-email':true}" aria-required="true">
</div>
</div>
<div class="field telephone ">
<label class="label" for="telephone"><span>Phone Number</span></label>
<div class="control">
<input name="phone" id="telephone" title="Phone Number" value="" class="input-text"
type="text">
</div>
</div>
<div class="field inquiry required">
<label class="label" for="inquiry"><span>Inquiry detail</span></label>
<div class="control">
<textarea readonly name="inquiry" id="inquiry" title="Inquiry" class="input-text"
cols="5" rows="5" data-validate="{required:true}" aria-required="true"></textarea>
</div>
</div>
<div class="field note">
<label class="label" for="note"><span>Note</span></label>
<div class="control">
<textarea name="note" id="note" title="Note" class="input-text"
cols="5" rows="5" aria-required="true"></textarea>
</div>
</div>
</fieldset>
<div class="actions-toolbar">
<div class="primary">
<button type="submit" title="Submit" class="action submit primary">
<span>Send Us</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
<script>
require(['jquery', 'cart_to_quote'], function($, cart_to_quote) {
$( document ).ready(function() {
window.isCleanCart = 0;
function listenCleanCart() {
console.log("message-success.success.message : ", $(".message-success.success.message").length);
if ($(".message-success.success.message").length > 0) {
window.isCleanCart = 6;
cart_to_quote.clearItems();
cart_to_quote.updateCounternumber();
}
// 10 second listen
if (window.isCleanCart < 6) {
window.isCleanCart++;
setTimeout(function() {
listenCleanCart();
}, 1000);
}
}
listenCleanCart();
});
});
</script>

View File

@ -0,0 +1,46 @@
<div class="columns">
<div class="column main">
<div class="cart-container">
<div class="cart-summary" style="top: 0px;">
<strong class="summary title">Request Quote</strong>
<br>
<h3 class="total-cart-quote"></h3>
<ul class="checkout methods items checkout-methods-items">
<li class="item"> <a href="<?php echo $this->getBaseUrl() .'carttoquote/request/quote'; ?>" type="button" data-role="proceed-to-checkout" title="Submit"
class="action primary checkout">
<span>Submit</span>
</a>
</li>
</ul>
</div>
<div id="form-validate"
class="form form-cart cart-quote">
<div class="cart table-wrapper">
<table id="shopping-cart-table" class="cart items data table">
<caption role="heading" aria-level="2" class="table-caption">Shopping Cart Items</caption>
<thead>
<tr>
<th class="col item" scope="col"><span>Item</span></th>
<!-- <th class="col price" scope="col"><span>Price</span></th> -->
<th class="col qty" scope="col"><span>Qty</span></th>
<th class="col subtotal" scope="col"><span>Action</span></th>
</tr>
</thead>
<tbody class="cart item cart-quote-content">
</tbody>
</table>
</div>
<div class="cart main actions">
<button class="cart-quote-clean" style="display:none">
<span>Clean Cart</span>
</button>
</div>
</div>
</div>
</div>
</div>

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,484 @@
define([
"jquery"
], function($){
"use strict";
var cart_to_quote = {
dataname : "cart_to_quote",
init : function() {
//this.displayAddToQuoteButton();
this.updateCounternumber();
this.bindClickAddToQuote();
this.renderCartQuotedetail();
this.bindClickCleanCart();
this.updateInquiry();
console.log("cart_to_quote init");
},
getData : function() {
if (this.dataname in localStorage) {
return JSON.parse(localStorage.getItem(this.dataname));
} else {
return null;
}
},
setData : function(data) {
localStorage.setItem(this.dataname, JSON.stringify(data));
},
getCurrentEmail : function() {
if ("email" in localStorage) {
return localStorage.getItem("email");
} else {
return "";
}
},
setCurrentEmail : function(email) {
localStorage.setItem("email", email);
},
addItem : function(item) {
if (!this.isExistItem(item)) {
var data = [];
if (this.dataname in localStorage) {
data = JSON.parse(localStorage.getItem(this.dataname));
data.push(item);
localStorage.setItem(this.dataname, JSON.stringify(data));
} else {
data.push(item)
localStorage.setItem(this.dataname, JSON.stringify(data));
}
}
},
updateQtyById : function(qty, product_id) {
if (this.dataname in localStorage) {
var data = JSON.parse(localStorage.getItem(this.dataname));
for (let i = 0; i < data.length; i++) {
if (data[i].product_id == product_id) {
data[i].qty = qty;
localStorage.setItem(this.dataname, JSON.stringify(data));
break;
}
}
}
},
deleteById : function(product_id) {
if (this.dataname in localStorage) {
var data = JSON.parse(localStorage.getItem(this.dataname));
for (let i = 0; i < data.length; i++) {
if (data[i].product_id == product_id) {
data.splice(i, 1);
localStorage.setItem(this.dataname, JSON.stringify(data));
break;
}
}
}
},
isData : function() {
if (this.getData() != null) {
return true;
}
return false;
},
isExistItem : function(item) {
if (this.dataname in localStorage) {
var data = JSON.parse(localStorage.getItem(this.dataname));
for (let i = 0; i < data.length; i++) {
if (data[i].product_id == item.product_id) {
return true;
}
}
}
return false;
},
getSizeItem : function(){
if (this.dataname in localStorage) {
return JSON.parse(localStorage.getItem(this.dataname)).length;
}
return 0;
},
getItemByProductId : function(product_id){
if (this.dataname in localStorage) {
var data = JSON.parse(localStorage.getItem(this.dataname));
for (let i = 0; i < data.length; i++) {
if (data[i].product_id == product_id) {
return data[i];
}
}
}
return null;
},
clearItems : function(){
localStorage.removeItem(this.dataname);
},
updateCounternumber : function(){
$(".menu-cart-quote .counter-number").html(this.getSizeItem());
if ($(".cart-quote-clean").length > 0 ) {
$(".total-cart-quote").html("Total : " + this.getSizeItem());
}
if ($(".cart-quote-clean").length > 0 ) {
if (this.getSizeItem() > 0) {
$(".cart-quote-clean").show();
} else {
$(".cart-quote-clean").hide();
}
}
},
showToastAddedToQuote :function() {
iqwerty.toast.toast('Added to quote', {
style: {
main: {
'background': '#218838',
'color': 'white',
'width': '200px',
},
},
});
},
showToastError :function() {
iqwerty.toast.toast('Error', {
style: {
main: {
'background': '#c82333',
'color': 'white',
'width': '200px',
},
},
});
},
showToastUpdateCartSuccessful :function() {
iqwerty.toast.toast('Update successful', {
style: {
main: {
'background': '#218838',
'color': 'white',
'width': '200px',
},
},
});
},
showToastRemoveCartSuccessful :function() {
iqwerty.toast.toast('Remove successful', {
style: {
main: {
'background': '#28a745',
'color': 'white',
'width': '200px',
},
},
});
},
bindClickAddToQuote : function() {
var root = this;
if ($("#product-addtocartquote-button").length > 0 ) {
$("#product-addtocartquote-button").click(function() {
if (!root.isExistItem (window._product)){
if (root.getCurrentEmail() != "" ) {
root.addProductToDb();
} else {
root.addItem(window._product);
root.updateCounternumber();
//$("#product-addtocartquote-button").hide();
$("#product-addtocartquote-button").attr("disabled", true);
root.showToastAddedToQuote();
}
}
});
}
},
displayAddToQuoteButton : function() {
if ($("#product-addtocartquote-button").length > 0 ) {
if (window._product != undefined) {
if (!this.isExistItem(window._product)) {
$("#product-addtocartquote-button").removeAttr("disabled");
//$("#product-addtocartquote-button").show();
} else {
$("#product-addtocartquote-button").attr("disabled", true);
//$("#product-addtocartquote-button").hide();
}
}
}
},
renderCartQuotedetail : function() {
if ($(".cart-quote-content").length > 0 ) {
if (this.isData()) {
var data = this.getData();
data.sort((a, b) => a.name.localeCompare(b.name));
$(".cart-quote-content").html("");
for (let i = 0; i < data.length; i++) {
var html ='<tr class="item-info cart-quote-content-row-'+ data[i].product_id +'">'+
'<td data-th="Item" class="col item">'+
'<a href="'+ data[i].url +'"'+
'title="'+ data[i].name +'" tabindex="-1" class="product-item-photo">'+
'<span class="product-image-container" style="width:165px;">'+
'<span class="product-image-wrapper" style="padding-bottom: 100%;">'+
'<img class="product-image-photo"'+
'src="'+ data[i].image +'"'+
'style="width:100px"></span>'+
'</span>'+
'</a>'+
'<div class="product-item-details">'+
'<strong class="product-item-name">'+
'<a href="'+ data[i].url +'">'+ data[i].name +'</a>'+
'</strong>'+
'</div>'+
'</td>'+
// '<td class="col price" data-th="Price">'+
// '<span class="price-excluding-tax" data-label="Excl. Tax">'+
// '<span class="cart-price">'+
// '<span class="price">$' + data[i].price + '</span> </span>'+
// '</span>'+
// '</td>'+
'<td class="col qty" data-th="Qty">'+
'<div class="field qty">'+
'<label class="label" for="cart-1-qty">'+
'<span>Qty</span>'+
'</label>'+
'<div class="control qty">'+
'<input product_id="'+ data[i].product_id +'" id="cart-qty-'+ data[i].product_id +'" value="'+ data[i].qty +'" type="number" title="Qty" class="input-text qty input-qty-item-quote">'+
'</div>'+
'</div>'+
'</td>'+
'<td style="text-align: center;" class="col action" data-th="Action">'+
'<button style="display:none" class="update" product_id="'+ data[i].product_id +'" title="Update">'+
'<span> Update </span>'+
'</button>'+
'<button class="remove" product_id="'+ data[i].product_id +'" title="Remove item">'+
'<span> Remove item </span>'+
'</button>'+
'</td>'+
'</tr>';
$(".cart-quote-content").append(html);
}
this.bindEventUpdateForCartItem();
this.bindEventRemoveForCartItem();
}
}
},
bindEventUpdateForCartItem : function() {
var root = this;
$(".cart-quote-content button.update").click(function() {
var product_id = $(this).attr("product_id");
var qty = $("#cart-qty-"+ product_id).val();
if (qty == '') {
qty = 0;
}
if (root.getCurrentEmail() != "" ) {
var product = root.getItemByProductId(product_id);
if (!product != null) {
product.qty = qty;
root.updateProductOnDb(product, $(this));
}
} else {
root.updateQtyById(qty, product_id);
root.showToastUpdateCartSuccessful();
}
});
$( ".input-qty-item-quote" ).on( "change", function() {
var product_id = $(this).attr("product_id");
var qty = $("#cart-qty-"+ product_id).val();
if (qty == '') {
qty = 0;
}
if (root.getCurrentEmail() != "" ) {
var product = root.getItemByProductId(product_id);
if (!product != null) {
product.qty = qty;
root.updateProductOnDb(product, $(this));
}
} else {
root.updateQtyById(qty, product_id);
root.showToastUpdateCartSuccessful();
}
});
},
bindEventRemoveForCartItem : function() {
var root = this;
$(".cart-quote-content button.remove").click(function() {
var product_id = $(this).attr("product_id");
if (root.getCurrentEmail() != "" ) {
var product = root.getItemByProductId(product_id);
if (!product != null) {
root.removeProductOnDb(product, $(this));
}
} else {
root.deleteById(product_id);
root.updateCounternumber();
$(".cart-quote-content-row-"+ product_id).remove();
root.showToastRemoveCartSuccessful();
}
});
},
bindClickCleanCart : function() {
if ($(".cart-quote-clean").length > 0 ) {
var root = this;
$(".cart-quote-clean").click(function() {
let text = "Are you sure to delete?";
if (confirm(text) == true) {
if (root.getCurrentEmail() != "" ) {
root.cleanProductOnDb($(this));
} else {
root.clearItems();
$(".cart-quote-content").html("");
root.updateCounternumber();
root.showToastRemoveCartSuccessful();
}
}
})
}
},
updateInquiry : function() {
if ($("#inquiry").length > 0) {
if (this.isData()) {
var data = this.getData();
data.sort((a, b) => a.name.localeCompare(b.name));
var inquirys = [];
for (let i = 0; i < data.length; i++) {
inquirys.push(data[i].sku + " : " + data[i].qty);
}
$("#inquiry").val(inquirys.join(" . \n"));
}
}
},
getDataFromDb : function() {
var root = this;
$.ajax({
type: "GET",
url: $(".menu-cart-quote").attr("host")+"carttoquote/quote/data",
error: function(xhr) {
// root.showToastError();
console.log(xhr);
},
success: function(data)
{
root.setData(JSON.parse(data));
$( document ).ready(function() {
root.init();
});
}
});
},
addProductToDb : function() {
var root = this;
var postData = window._product;
$.ajax({
type: "POST",
url: $(".menu-cart-quote").attr("host")+"carttoquote/quote/additem",
dataType : "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(postData),
beforeSend: function() {
$("#product-addtocartquote-button span").html("Adding to Quote");
$("#product-addtocartquote-button").attr("disabled", true);
},
error: function(xhr) {
$("#product-addtocartquote-button").attr("disabled", true);
root.showToastError();
},
success: function(data){
root.setData(data);
root.displayAddToQuoteButton();
root.updateCounternumber();
root.showToastAddedToQuote();
},
complete: function() {
$("#product-addtocartquote-button span").html("Add to Quote");
//$("#product-addtocartquote-button").removeAttr("disabled");
},
});
},
updateProductOnDb : function(product, context) {
var root = this;
var postData = {
data : product
};
$.ajax({
type: "POST",
url: $(".menu-cart-quote").attr("host")+"rest/all/V1/request/quote/update_item",
dataType : "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(postData),
beforeSend: function() {
context.find("span").html("Updating");
context.attr("disabled", true);
},
error: function(xhr) {
root.showToastError();
},
success: function(data){
root.setData(data);
root.showToastRemoveCartSuccessful();
},
complete: function() {
context.find("span").html("Update");
context.removeAttr("disabled");
},
});
},
removeProductOnDb : function(product, context) {
var root = this;
var postData = {
data : product
};
$.ajax({
type: "POST",
url: $(".menu-cart-quote").attr("host")+"rest/all/V1/request/quote/remove_item",
dataType : "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(postData),
beforeSend: function() {
context.find("span").html("Removing item");
context.attr("disabled", true);
},
error: function(xhr) {
root.showToastError();
},
success: function(data){
$(".cart-quote-content-row-"+ product.product_id).remove();
root.setData(data);
root.updateCounternumber();
root.showToastRemoveCartSuccessful();
},
complete: function() {
context.find("span").html("Remove item");
context.removeAttr("disabled");
},
});
},
cleanProductOnDb : function(context) {
var root = this;
var postData = {
data : {}
};
$.ajax({
type: "POST",
url: $(".menu-cart-quote").attr("host")+"carttoquote/quote/clean",
dataType : "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(postData),
beforeSend: function() {
context.find("span").html("Cleanning Cart");
context.attr("disabled", true);
},
error: function(xhr) {
root.showToastError();
},
success: function(data){
root.setData([]);
$(".cart-quote-content").html("");
root.updateCounternumber();
root.showToastRemoveCartSuccessful();
},
complete: function() {
context.find("span").html("Clean Cart");
context.removeAttr("disabled");
},
});
}
}
return cart_to_quote;
});

View File

@ -0,0 +1 @@
!function(t){"use strict";function n(t,r){var e=r;for(var i in t)e.hasOwnProperty(i)?null!==t[i]&&t[i].constructor===Object&&(e[i]=n(t[i],e[i])):e[i]=t[i];return e}function r(t,n){Object.keys(n).forEach((function(r){t.style[r]=n[r]}))}var e=function(){var t,e,i={SHOW:{"-webkit-transition":"opacity 400ms, -webkit-transform 400ms",transition:"opacity 400ms, transform 400ms",opacity:"1","-webkit-transform":"translateY(-100%) translateZ(0)",transform:"translateY(-100%) translateZ(0)"},HIDE:{opacity:"0","-webkit-transform":"translateY(150%) translateZ(0)",transform:"translateY(150%) translateZ(0)"}},a={style:{main:{background:"rgba(0, 0, 0, .85)","box-shadow":"0 0 10px rgba(0, 0, 0, .8)","border-radius":"3px","z-index":"99999",color:"rgba(255, 255, 255, .9)","font-family":"sans-serif",padding:"10px 15px","max-width":"60%",width:"100%","word-break":"keep-all",margin:"0 auto","text-align":"center",position:"fixed",left:"0",right:"0",bottom:"0","-webkit-transform":"translateY(150%) translateZ(0)",transform:"translateY(150%) translateZ(0)","-webkit-filter":"blur(-1)",opacity:"0"}},settings:{duration:4e3}},o=[];function s(t,s,c){var l=c||i;if(void 0!==f())o.push({text:t,options:s,transitions:l});else{var m=s||{};(function(t,n,i){!function(t,n){var e=document.createElement("div");"string"==typeof t&&(t=document.createTextNode(t));e.appendChild(t),d(e),r(f(),n)}(t,n.style.main);var a=f();document.body.insertBefore(a,document.body.firstChild),a.offsetHeight,r(a,i.SHOW),clearTimeout(e),0!==n.settings.duration&&(e=setTimeout((function(){return u(i)}),n.settings.duration))})(t,m=n(a,m),l)}return{hide:function(){return u(l)}}}function u(t){var n=f();r(n,t.HIDE),clearTimeout(e),n.addEventListener("transitionend",c,{once:!0})}function c(){var t=f();if(document.body.removeChild(t),d(void 0),o.length>0){var n=o.shift();s(n.text,n.options,n.transitions)}}function f(){return t}function d(n){t=n}return{toast:s}}();t.mergeOptions=n,t.stylize=r,t.toast=e}(this.iqwerty=this.iqwerty||{});

View File

@ -0,0 +1,26 @@
<?php
namespace IpSupply\CatalogSearch\Override\Magento\Catalog\Ui\DataProvider\Product;
class ProductDataProvider extends \Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider
{
/**
* Add the category id to filter
*
* @param \Magento\Framework\Api\Filter $filter
*/
public function addFilter(\Magento\Framework\Api\Filter $filter)
{
if ($filter->getField() == 'category_id') {
$this->getCollection()->addCategoriesFilter(['in' => $filter->getValue()]);
} elseif (isset($this->addFilterStrategies[$filter->getField()])) {
$this->addFilterStrategies[$filter->getField()]
->addFilter(
$this->getCollection(),
$filter->getField(),
[$filter->getConditionType() => $filter->getValue()]
);
} else {
parent::addFilter($filter);
}
}
}

View File

@ -0,0 +1,81 @@
<?php
namespace IpSupply\CatalogSearch\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
class Category extends \Magento\Ui\Component\Listing\Columns\Column
{
/**
* @var \Magento\Catalog\Model\ProductCategoryList
*/
private $productCategory;
/**
* @var \Magento\Catalog\Api\CategoryRepositoryInterface
*/
private $categoryRepository;
/**
* @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
* @param \Magento\Framework\View\Element\UiComponentFactory $uiComponentFactory
* @param array $components
* @param array $data
* @param \Magento\Catalog\Model\ProductCategoryList $productCategory
* @param \Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository
*/
public function __construct(
\Magento\Catalog\Api\CategoryRepositoryInterface $categoryRepository,
\Magento\Catalog\Model\ProductCategoryList $productCategory,
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
array $components = [],
array $data = []
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->productCategory = $productCategory;
$this->categoryRepository = $categoryRepository;
}
/**
* Prepare data for the category column
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
$fieldName = $this->getData('name');
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as &$item) {
$productId = $item['entity_id'];
$categoryIds = $this->getCategoryIds($productId);
$categories = [];
if (count($categoryIds)) {
foreach ($categoryIds as $categoryId) {
$categoryData = $this->categoryRepository->get($categoryId);
$categories[] = $categoryData->getName();
}
}
$item[$fieldName] = implode(', ', $categories);
}
}
return $dataSource;
}
/**
* Retrieve all the category ids
*
* @param integer $productId
* @return array
*/
private function getCategoryIds($productId)
{
$categoryIds = $this->productCategory->getCategoryIds($productId);
$_categoryIds = [];
if ($categoryIds) {
$_categoryIds = array_unique($categoryIds);
}
return $_categoryIds;
}
}

View File

@ -0,0 +1,105 @@
<?php
namespace IpSupply\CatalogSearch\Ui\Component\Product\Form\Categories;
use Magento\Framework\Data\OptionSourceInterface;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
use Magento\Framework\App\RequestInterface;
use Magento\Catalog\Model\Category as CategoryModel;
/**
* Options tree for "Categories" field
*/
class Options implements OptionSourceInterface
{
/**
* @var \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory
*/
protected $categoryCollectionFactory;
/**
* @var RequestInterface
*/
protected $request;
/**
* @var array
*/
protected $categoriesTree;
/**
* @param CategoryCollectionFactory $categoryCollectionFactory
* @param RequestInterface $request
*/
public function __construct(
CategoryCollectionFactory $categoryCollectionFactory,
RequestInterface $request
) {
$this->categoryCollectionFactory = $categoryCollectionFactory;
$this->request = $request;
}
/**
* {@inheritdoc}
*/
public function toOptionArray()
{
return $this->getCategoriesTree();
}
/**
* Retrieve categories tree
*
* @return array
*/
protected function getCategoriesTree()
{
if ($this->categoriesTree === null) {
$storeId = $this->request->getParam('store');
/* @var $matchingNamesCollection \Magento\Catalog\Model\ResourceModel\Category\Collection */
$matchingNamesCollection = $this->categoryCollectionFactory->create();
$matchingNamesCollection->addAttributeToSelect('path')
->addAttributeToFilter('entity_id', ['nin' => [CategoryModel::TREE_ROOT_ID, '3', '2']])
->setStoreId($storeId);
$shownCategoriesIds = [];
/** @var \Magento\Catalog\Model\Category $category */
foreach ($matchingNamesCollection as $category) {
foreach (explode('/', $category->getPath()) as $parentId) {
$shownCategoriesIds[$parentId] = 1;
}
}
/* @var $collection \Magento\Catalog\Model\ResourceModel\Category\Collection */
$collection = $this->categoryCollectionFactory->create();
$collection->addAttributeToFilter('entity_id', ['in' => array_keys($shownCategoriesIds)])
->addAttributeToSelect(['name', 'is_active', 'parent_id'])
->setStoreId($storeId);
$categoryById = [
CategoryModel::TREE_ROOT_ID => [
'value' => CategoryModel::TREE_ROOT_ID
],
];
foreach ($collection as $category) {
foreach ([$category->getId(), $category->getParentId()] as $categoryId) {
if (!isset($categoryById[$categoryId])) {
$categoryById[$categoryId] = ['value' => $categoryId];
}
}
$categoryById[$category->getId()]['is_active'] = $category->getIsActive();
$categoryById[$category->getId()]['label'] = $category->getName();
$categoryById[$category->getParentId()]['optgroup'][] = &$categoryById[$category->getId()];
}
$this->categoriesTree = $categoryById[CategoryModel::TREE_ROOT_ID]['optgroup'];
}
return $this->categoriesTree;
}
}

View File

@ -0,0 +1,27 @@
{
"name": "ipsupply/catalogsearch",
"description": "Catalog Search",
"require": {
"php": "~7.1.3||~7.2.0",
"lib-libxml": "*",
"magento/framework": "102.0.*",
"magento/module-backend": "101.0.*",
"magento/module-media-storage": "100.3.*",
"magento/module-store": "101.0.*",
"magento/module-ui": "101.1.*"
},
"type": "magento2-module",
"version": "100.3.0",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"IpSupply\\CatalogSearch\\": ""
}
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider" type="IpSupply\CatalogSearch\Override\Magento\Catalog\Ui\DataProvider\Product\ProductDataProvider" />
</config>

View File

@ -0,0 +1,5 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="IpSupply_CatalogSearch" setup_version="1.0.0">
</module>
</config>

View File

@ -0,0 +1,7 @@
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'IpSupply_CatalogSearch',
__DIR__
);

View File

@ -0,0 +1,34 @@
<?xml version="1.0"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<listingToolbar name="listing_top">
<filters name="listing_filters">
<filterSelect name="category_id" provider="${ $.parentName }" component="Magento_Ui/js/form/element/ui-select" template="ui/grid/filters/elements/ui-select">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filterOptions" xsi:type="boolean">true</item>
<item name="levelsVisibility" xsi:type="number">1</item>
</item>
</argument>
<settings>
<options class="IpSupply\CatalogSearch\Ui\Component\Product\Form\Categories\Options"/>
<caption translate="true"> Please Select a Category </caption>
<label translate="true">Categories</label>
<dataScope>category_id</dataScope>
<imports>
<link name="visible">componentType = column, index = ${ $.index }:visible</link>
</imports>
</settings>
</filterSelect>
</filters>
</listingToolbar>
<columns name="product_columns" class="Magento\Catalog\Ui\Component\Listing\Columns">
<column name="category_id" class="IpSupply\CatalogSearch\Ui\Component\Listing\Column\Category">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Categories</item>
<item name="sortOrder" xsi:type="number">110</item>
</item>
</argument>
</column>
</columns>
</listing>

View File

@ -0,0 +1,208 @@
<?php
namespace IpSupply\CategoryApi\Api\Controller;
use IpSupply\CategoryApi\Api\Interface\CategoryApiInterface;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\Webapi\Rest\Request;
use Magento\Framework\App\ObjectManager;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Store\Model\StoreManagerInterface;
class CategoryApiController extends AbstractHelper implements CategoryApiInterface {
protected $_request;
protected $_objectManager;
protected $_productRepository;
protected $_storeManager;
protected $_baseURL;
public function __construct(Context $context, Request $request, ProductRepositoryInterface $productRepository, StoreManagerInterface $storeManager) {
$this->_request = $request;
$this->_objectManager = ObjectManager::getInstance();
$this->_productRepository = $productRepository;
$this->_storeManager = $storeManager;
$this->_baseURL = $this->_storeManager->getStore()->getBaseUrl();
parent::__construct($context);
}
/*
request structure:
{
category_id: <id of category>
}
*/
public function getProductByCategory() {
try {
$request = $this->_request->getParams();
if (isset($request["category_id"])) {
$response = [];
$categoryFactory = $this->_objectManager->get('\Magento\Catalog\Model\CategoryFactory');
$categoryID = $this->_request->getParams()['category_id'];
$category = $categoryFactory->create()->load($categoryID);
$products = $category->getProductCollection()->addAttributeToSelect('*')->addFieldToFilter('type_id', 'configurable');
foreach($products as $product) {
$dataResponse = [];
$dataResponse["sku"] = $product->getSku();
$dataResponse["name"] = $product->getSku();
$dataResponse["categories"] = [(int)$categoryID];
$dataResponse["description"] = "";
$dataResponse["shortDescription"] = "";
$dataResponse["imageUrls"] = $this->getProductImageURL($product);
$dataResponse["brands"] = "";
if($product->getResource()->getAttribute("brands") != false) {
if($product->getResource()->getAttribute("brands")->getFrontend()->getValue($product) != false) {
$dataResponse["brands"] = $product->getResource()->getAttribute("brands")->getFrontend()->getValue($product);
}
}
$dataResponse["types"] = "";
if($product->getResource()->getAttribute("types") != false) {
if($product->getResource()->getAttribute("types")->getFrontend()->getValue($product) != false) {
$dataResponse["types"] = $product->getResource()->getAttribute("types")->getFrontend()->getValue($product);
}
}
$dataResponse["condition"] = $this->getProductVariants($product);
$dataResponse["relatedProduct"] = $this->getRelatedProduct($product, $categoryID);
$dataResponse["upsellProduct"] = $this->getUpSellProduct($product, $categoryID);
$dataResponse["crosssellProduct"] = $this->getCrossSellProduct($product, $categoryID);
$response[] = $dataResponse;
}
return $response;
}
else {
return json_encode(["code" => 500, "message" => "Incorrect argument"]);
}
}
catch (Exception $e) {
return json_encode(["code" => 500, "message" => "Error".$e]);
}
}
public function getProductImageURL($product) {
return $product["thumbnail"] != "" ? [$this->_baseURL."media/catalog/product".$product["thumbnail"]] : [];
}
public function getProductVariants($product) {
$productVariants = $product->getTypeInstance()->getUsedProducts($product);
if(!empty($productVariants)) {
$response = [];
foreach($productVariants as $variant) {
$optionText = $variant->getResource()->getAttribute('choose_condition')->getFrontend()->getValue($variant);
$response[strtolower($optionText)] = array(
// "qty" => $variant->getQty(),
"qty" => 0,
"price" => $variant->getPrice(),
"imageUrls" => $this->getProductImageURL($variant)
);
}
return $response;
}
else {
return null;
}
}
public function getRelatedProduct($rootProduct, $categoryID) {
$response = [];
$relatedProduct = $rootProduct->getRelatedProducts();
$productRepo = $this->_objectManager->get('\Magento\Catalog\Model\ProductRepository');
if(!empty($relatedProduct)) {
foreach($relatedProduct as $product) {
$dataResponse = [];
$productData = $productRepo->getById($product->getID());
$dataResponse["sku"] = $productData->getSku();
$dataResponse["name"] = $product->getSku();
$dataResponse["categories"] = [(int)$categoryID];
$dataResponse["description"] = "";
$dataResponse["shortDescription"] = "";
$dataResponse["imageUrls"] = $this->getProductImageURL($productData);
$dataResponse["brands"] = "";
if($productData->getResource()->getAttribute("brands") != false) {
if($productData->getResource()->getAttribute("brands")->getFrontend()->getValue($productData) != false) {
$dataResponse["brands"] = $productData->getResource()->getAttribute("brands")->getFrontend()->getValue($productData);
}
}
$dataResponse["types"] = "";
if($productData->getResource()->getAttribute("types") != false) {
if($productData->getResource()->getAttribute("types")->getFrontend()->getValue($productData) != false) {
$dataResponse["types"] = $productData->getResource()->getAttribute("types")->getFrontend()->getValue($productData);
}
}
$dataResponse["condition"] = $this->getProductVariants($productData);
$response[] = $dataResponse;
}
}
return $response;
}
public function getUpSellProduct($rootProduct, $categoryID) {
$response = [];
$upSellProduct = $rootProduct->getUpSellProducts();
$productRepo = $this->_objectManager->get('\Magento\Catalog\Model\ProductRepository');
if(!empty($upSellProduct)) {
foreach($upSellProduct as $product) {
$dataResponse = [];
$productData = $productRepo->getById($product->getID());
$dataResponse["sku"] = $productData->getSku();
$dataResponse["name"] = $product->getSku();
$dataResponse["categories"] = [(int)$categoryID];
$dataResponse["description"] = "";
$dataResponse["shortDescription"] = "";
$dataResponse["imageUrls"] = $this->getProductImageURL($productData);
$dataResponse["brands"] = "";
if($productData->getResource()->getAttribute("brands") != false) {
if($productData->getResource()->getAttribute("brands")->getFrontend()->getValue($productData) != false) {
$dataResponse["brands"] = $productData->getResource()->getAttribute("brands")->getFrontend()->getValue($productData);
}
}
$dataResponse["types"] = "";
if($productData->getResource()->getAttribute("types") != false) {
if($productData->getResource()->getAttribute("types")->getFrontend()->getValue($productData) != false) {
$dataResponse["types"] = $productData->getResource()->getAttribute("types")->getFrontend()->getValue($productData);
}
}
$dataResponse["condition"] = $this->getProductVariants($productData);
$response[] = $dataResponse;
}
}
return $response;
}
public function getCrossSellProduct($rootProduct, $categoryID) {
$response = [];
$crossSellProduct = $rootProduct->getCrossSellProducts();
$productRepo = $this->_objectManager->get('\Magento\Catalog\Model\ProductRepository');
if(!empty($crossSellProduct)) {
foreach($crossSellProduct as $product) {
$dataResponse = [];
$productData = $productRepo->getById($product->getID());
$dataResponse["sku"] = $productData->getSku();
$dataResponse["name"] = $product->getSku();
$dataResponse["categories"] = [(int)$categoryID];
$dataResponse["description"] = "";
$dataResponse["shortDescription"] = "";
$dataResponse["imageUrls"] = $this->getProductImageURL($productData);
$dataResponse["brands"] = "";
if($productData->getResource()->getAttribute("brands") != false) {
if($productData->getResource()->getAttribute("brands")->getFrontend()->getValue($productData) != false) {
$dataResponse["brands"] = $productData->getResource()->getAttribute("brands")->getFrontend()->getValue($productData);
}
}
$dataResponse["types"] = "";
if($productData->getResource()->getAttribute("types") != false) {
if($productData->getResource()->getAttribute("types")->getFrontend()->getValue($productData) != false) {
$dataResponse["types"] = $productData->getResource()->getAttribute("types")->getFrontend()->getValue($productData);
}
}
$dataResponse["condition"] = $this->getProductVariants($productData);
$response[] = $dataResponse;
}
}
return $response;
}
}

View File

@ -0,0 +1,11 @@
<?php
namespace IpSupply\CategoryApi\Api\Interface;
interface CategoryApiInterface {
/**
* Api for get product by category
* @return array
*/
public function getProductByCategory();
}

View File

@ -0,0 +1,36 @@
<?php
namespace IpSupply\CategoryApi\Helper;
use Magento\Catalog\Model\ProductRepository;
class ProductHelper
{
protected $productRepository;
protected $objectManager;
public function __construct(
ProductRepository $productRepository,
) {
$this->productRepository = $productRepository;
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
}
public function removeDisallowedLinks($sku) {
$productObject = $this->objectManager->get('Magento\Catalog\Model\Product');
$product = $productObject->loadByAttribute("sku", $sku);
if ($product) {
$product = $product->getCollection()
->addFieldToSelect("*")
->addAttributeToFilter('sku', $sku)
->addMediaGalleryData()
->getFirstItem();
echo $sku." is exist";
$product->setName("test");
$product->save();
} else {
echo $sku." not exist";
}
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="IpSupply\CategoryApi\Api\Interface\CategoryApiInterface"
type="IpSupply\CategoryApi\Api\Controller\CategoryApiController"/>
</config>

View File

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="IpSupply_CategoryApi" setup_version="1.0.0"></module>
</config>

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
<route method="GET" url="/V1/client/get-product-by-category">
<service class="IpSupply\CategoryApi\Api\Interface\CategoryApiInterface" method="getProductByCategory"/>
<resources>
<resource ref="anonymous"/>
</resources>
</route>
</routes>

View File

@ -0,0 +1,5 @@
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::MODULE, "IpSupply_CategoryApi", __DIR__);

View File

@ -0,0 +1,244 @@
<?php
namespace IpSupply\ChatMessage\Api\Controller;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request as GuzzRequest;
use IpSupply\ChatMessage\Api\Interface\MessageApiInterface;
use IpSupply\ChatMessage\Config\ChatConfig;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\Webapi\Rest\Request;
class MessageApi extends AbstractHelper implements MessageApiInterface {
protected $_request;
protected $_chatConfig;
public function __construct(Context $context, Request $request) {
$this->_request = $request;
// $this->_chatConfig = $_chatConfig;
parent::__construct($context);
}
public function getMessage() {
try {
$topic = $this->_request->getParams()["topic"];
$streamName = $this->_chatConfig->getStreamName();
$client = new Client();
$headers = [
'Authorization' => $this->_chatConfig->getZulipAuthToken()
];
$url = $this->_chatConfig->getHostDomain().'api/v1/messages?anchor=newest&num_before=100&num_after=0&narrow=[{"operator":"stream","operand":"'.$streamName.'"},{"operator":"topic","operand":"'.$topic.'"}]&apply_markdown=false';
$request = new GuzzRequest('GET', $url, $headers);
$promise = $client->sendAsync($request)->then(function ($response) {
echo $response->getBody();
exit();
});
$promise->wait();
}
catch (\Exception $e) {
return json_encode(["code" => 500, "message" => "Error".$e]);
}
}
public function getMessageUnRead() {
try {
$topic = $this->_request->getParams()["topic"];
$streamName = $this->_chatConfig->getStreamName();
$client = new Client();
$headers = [
'Authorization' => $this->_chatConfig->getZulipAuthToken()
];
$url = $this->_chatConfig->getHostDomain().'api/v1/messages?anchor=first_unread&num_before=0&num_after=99&narrow=[{"operator":"stream","operand":"'.$streamName.'"},{"operator":"topic","operand":"'.$topic.'"}]&apply_markdown=false';
$request = new GuzzRequest('GET', $url, $headers);
$promise = $client->sendAsync($request)->then(function ($response) {
echo $response->getBody();
exit();
});
$promise->wait();
}
catch (\Exception $e) {
return json_encode(["code" => 500, "message" => "Error".$e]);
}
}
public function registerQueue() {
try {
$topic = $this->_request->getParams()["topic"];
$streamName = $this->_chatConfig->getStreamName();
$client = new Client();
$headers = [
'Authorization' => $this->_chatConfig->getZulipAuthToken()
];
$options = [
'multipart' => [
[
'name' => 'event_types',
'contents' => '["message"]',
],
[
'name' => 'narrow',
'contents' => '[["stream", "'.$streamName.'"], ["topic", "'.$topic.'"]]',
]
]
];
$request = new GuzzRequest('POST', $this->_chatConfig->getHostDomain().'api/v1/register', $headers);
$promise = $client->sendAsync($request, $options)->then(function ($response) {
echo $response->getBody();
exit();
});
$promise->wait();
}
catch (\Exception $e) {
return json_encode(["code" => 500, "message" => "Error".$e]);
}
}
public function listenMessage() {
try {
$params = $this->_request->getParams();
$queueId = $params["queue_id"];
$lastEventId = $params["last_event_id"];
$client = new Client();
$headers = [
'Authorization' => $this->_chatConfig->getZulipAuthToken()
];
$url = $this->_chatConfig->getHostDomain().'api/v1/events?queue_id='.$queueId.'&last_event_id='.$lastEventId;
$request = new GuzzRequest('GET', $url, $headers);
$promise = $client->sendAsync($request)->then(function ($response) {
echo $response->getBody();
exit();
});
$promise->wait();
}
catch (\Exception $e) {
return json_encode(["code" => 500, "message" => "Error".$e]);
}
}
public function sendMessage() {
try {
$params = $this->_request->getParams();
$content = $params["content"];
$topic = $params["topic"];
$streamName = $this->_chatConfig->getStreamName();
$client = new Client();
$headers = [
'Authorization' => $this->_chatConfig->getZulipAuthToken()
];
$url = $this->_chatConfig->getHostDomain().'api/v1/messages';
$options = [
'multipart' => [
[
'name' => 'to',
'contents' => $streamName,
],
[
'name' => 'type',
'contents' => 'stream',
],
[
'name' => 'topic',
'contents' => $topic,
],
[
'name' => 'content',
'contents' => $content,
]
]
];
$request = new GuzzRequest('POST', $url, $headers);
$promise = $client->sendAsync($request, $options)->then(function ($response) {
return json_encode(["code" => 200, "message" => "Success"]);
});
$promise->wait();
}
catch (\Exception $e) {
return json_encode(["code" => 500, "message" => "Error".$e]);
}
}
public function markTopicAsRead() {
try {
$params = $this->_request->getParams();
$topic = $params["topic"];
$streamID = $this->_chatConfig->getStreamID();
$client = new Client();
$headers = [
'Authorization' => $this->_chatConfig->getZulipAuthToken()
];
$url = $this->_chatConfig->getHostDomain().'api/v1/mark_topic_as_read';
$options = [
'multipart' => [
[
'name' => 'stream_id',
'contents' => $streamID,
],
[
'name' => 'topic_name',
'contents' => $topic,
]
]
];
$request = new GuzzRequest('POST', $url, $headers);
$promise = $client->sendAsync($request, $options)->then(function ($response) {
return json_encode(["code" => 200, "message" => "Success"]);
});
$promise->wait();
}
catch (\Exception $e) {
return json_encode(["code" => 500, "message" => "Error".$e]);
}
}
/**
* Api for make offer
* @param string[] $data
* @return string
*/
public function makeAnOffer($data) {
try {
$topic = $data["customer-email"];
// $streamName = $this->_chatConfig->getStreamMakeOffer();
$streamName = $this->_chatConfig->getStreamName();
$content = "Product: [".$data["product-sku"]."](".$data["product-url"].") \nSell Price: **".$data["product-sell-price"]."** \nCustomer Offer Price: **".$data["customer-offer"]."** \nCustomer: ".$data["customer-name"]." \nEmail: ".$data["customer-email"]." \nPhone: ".$data["customer-mobile-phone"]." \nCustomer shipping destination: ".$data["customer-country"]." \nMessage: ".$data["customer-message"];
$client = new Client();
$headers = [
'Authorization' => $this->_chatConfig->getZulipAuthToken()
];
$url = $this->_chatConfig->getHostDomain().'api/v1/messages';
$options = [
'multipart' => [
[
'name' => 'to',
'contents' => $streamName,
],
[
'name' => 'type',
'contents' => 'stream',
],
[
'name' => 'topic',
'contents' => $topic,
],
[
'name' => 'content',
'contents' => $content,
]
]
];
$request = new GuzzRequest('POST', $url, $headers);
$promise = $client->sendAsync($request, $options)->then(function ($response) {
return true;
});
$promise->wait();
return $request->getBody()->getContents();
}
catch (\Exception $e) {
return false;
}
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace IpSupply\ChatMessage\Api\Interface;
interface MessageApiInterface {
/**
* Api for get message
* @return array
*/
public function getMessage();
/**
* Api for get message unread
* @return array
*/
public function getMessageUnRead();
/**
* Api for send message
* @return array
*/
public function sendMessage();
/**
* Api for register queue
* @return array
*/
public function registerQueue();
/**
* Api for listen message
* @return array
*/
public function listenMessage();
/**
* Api for listen message
* @return string
*/
public function markTopicAsRead();
/**
* Api for make offer
* @param string[] $data
* @return string
*/
public function makeAnOffer($data);
}

View File

@ -0,0 +1,43 @@
<?php
namespace IpSupply\ChatMessage\Block\Widget;
use Magento\Framework\View\Element\Template;
use Magento\Widget\Block\BlockInterface;
use Magento\Framework\View\Element\Template\Context;
use Magento\Framework\App\ObjectManager;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\UrlInterface;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request as GuzzRequest;
class ChatBlockControl extends Template implements BlockInterface {
protected $_objectManager;
protected $_storeManager;
public function __construct(StoreManagerInterface $_storeManager, Context $context, array $data = []) {
$this->_objectManager = ObjectManager::getInstance();
$this->_storeManager = $_storeManager;
parent::__construct($context, $data);
}
function getAssetUrl($asset) {
$assetRepository = $this->_objectManager->get('Magento\Framework\View\Asset\Repository');
return $assetRepository->createAsset($asset)->getUrl();
}
function getBaseUrl() {
$storeManager = $this->_objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$baseUrl = $storeManager->getStore()->getBaseUrl();
return $baseUrl;
}
function getCustomerInfo() {
$customerSession = $this->_objectManager->create('Magento\Customer\Model\Session');
if ($customerSession->isLoggedIn()) {
return ["logged" => True];
}
return ["logged" => False];
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace IpSupply\ChatMessage\Controller\Api;
use Magento\Framework\App\Action\Context;
class CurrentCustomerInfo extends \Magento\Framework\App\Action\Action {
protected $customerSession;
protected $objectManager;
public function __construct(
Context $context,
)
{
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->customerSession = $this->objectManager->get(\Magento\Customer\Model\Session::class);
parent::__construct($context);
}
public function execute()
{
if($this->customerSession->isLoggedIn()) {
$customer = $this->customerSession->getCustomer();
$response = array();
$response["email"] = $customer->getEmail();
$response["fullname"] = $customer->getName();
echo json_encode($response);
exit;
} else {
echo null;
exit;
}
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace IpSupply\ChatMessage\Controller\Api;
use Magento\Framework\App\Action\Context;
class Register extends \Magento\Framework\App\Action\Action {
protected $customerSession;
protected $objectManager;
public function __construct(
Context $context,
)
{
$this->objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$this->customerSession = $this->objectManager->get(\Magento\Customer\Model\Session::class);
parent::__construct($context);
}
public function execute()
{
if($this->customerSession->isLoggedIn()) {
$customer = $this->customerSession->getCustomer();
echo json_encode($customer->getEmail());
exit;
} else {
echo null;
exit;
}
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace IpSupply\ChatMessage\Helper;
class Authentication {
/**
* Username used for authentication
*
* @var string
*/
protected $username;
/**
* API key used for authentication
*
* @var string
*/
protected $apiKey;
public function __construct($username, $apiKey)
{
$this->setUsername($username);
$this->setApiKey($apiKey);
}
/**
* @return string
*/
public function getUsername()
{
return $this->username;
}
/**
* @param string $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* @return string
*/
public function getApiKey()
{
return $this->apiKey;
}
/**
* @param string $apiKey
*/
public function setApiKey($apiKey)
{
$this->apiKey = $apiKey;
}
}

View File

@ -0,0 +1,171 @@
<?php
namespace IpSupply\ChatMessage\Helper;
use GuzzleHttp\ClientInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use IpSupply\ChatMessage\Helper\Request\GetEventsParameters;
use IpSupply\ChatMessage\Helper\Request\MessageParameters;
use IpSupply\ChatMessage\Helper\Request\ParametersInterface;
use IpSupply\ChatMessage\Helper\Request\RegisterQueueParameters;
use IpSupply\ChatMessage\Helper\Request\RequestInterface;
use IpSupply\ChatMessage\Helper\Request\ValidationException;
class Client implements LoggerAwareInterface
{
use LoggerAwareTrait;
/**
* @var ClientInterface
*/
private $client;
/**
* @var Authentication
*/
private $defaultAuthentication;
/**
* @var string
*/
private $serverUrl;
public function __construct($serverUrl, LoggerInterface $logger = null)
{
$this->setLogger(is_null($logger) ? new NullLogger() : $logger);
$this->serverUrl = $serverUrl;
}
/**
* @param Authentication $defaultAuthentication
*/
public function setDefaultAuthentication($defaultAuthentication)
{
$this->defaultAuthentication = $defaultAuthentication;
}
/**
* Send message to zulip
*
* @param array|MessageParameters $messageParameters
* @return mixed
* @throws ValidationException
* @throws \Exception
*/
public function sendMessage($messageParameters)
{
if (is_array($messageParameters)) {
$messageParameters = new MessageParameters($messageParameters);
}
if (!$messageParameters instanceof MessageParameters) {
throw new \BadMethodCallException('$messageParameter must be an instance of MessageParameters or an array');
}
return $this->createRequest('\IpSupply\ChatMessage\Helper\Request\MessageRequest', $messageParameters);
}
/**
* Register a queue with zulip
*
* @param $queueParameters
* @return mixed
* @throws ValidationException
* @throws \Exception
*/
public function registerQueue($queueParameters)
{
if (is_array($queueParameters)) {
$queueParameters = new RegisterQueueParameters($queueParameters);
}
if (!$queueParameters instanceof RegisterQueueParameters) {
throw new \BadMethodCallException('$queueParameters must be an instance of RegisterQueueParameters or an array');
}
return $this->createRequest('\IpSupply\ChatMessage\Helper\Request\RegisterQueueRequest', $queueParameters);
}
/**
* Get events for queue
*
* @param $params
* @return mixed
* @throws ValidationException
* @throws \Exception
*/
public function getEventsFromQueue($params)
{
if (is_array($params)) {
$params = new GetEventsParameters($params);
}
if (!$params instanceof GetEventsParameters) {
throw new \BadMethodCallException('$params must be an instance of GetEventsParameters or an array');
}
return $this->createRequest('\IpSupply\ChatMessage\Helper\Request\GetEventsRequest', $params);
}
/**
* @return ClientInterface
*/
public function getHttpClient()
{
if (empty($this->client)) {
$this->setHttpClient(new \GuzzleHttp\Client());
}
return $this->client;
}
/**
* @param ClientInterface $client
*/
public function setHttpClient($client)
{
$this->client = $client;
}
/**
* @param $class
* @param ParametersInterface $parameters
* @return mixed
* @throws ValidationException
* @throws \Exception
*/
protected function createRequest($class, ParametersInterface $parameters)
{
$this->logger->info("Sending request type: '" . $class. "", ['params' => $parameters->getData()]);
$authentication = $parameters->getAuthentication();
if (is_null($authentication)) {
$authentication = $this->defaultAuthentication;
}
if (!$authentication instanceof Authentication) {
throw new \Exception('Missing authentication');
}
try {
/** @var RequestInterface $request */
$request = new $class($this->getHttpClient());
return $request->initialize($this->serverUrl, $parameters, $authentication);
}catch(ValidationException $e) {
$this->logger->error("Error during validation", [
'message' => $e->getMessage(),
'errors' => $e->getErrors(),
'params' => $parameters->getData()
]);
throw $e;
}catch(\Exception $e) {
$this->logger->error('Exception occurred', [
'message' => $e->getMessage(),
'params' => $parameters->getData()
]);
throw $e;
}
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
class GetEventsParameters extends ParametersAbstract
{
use SimpleParamTrait;
/**
* @inheritDoc
*/
public function __construct(array $parameters = [])
{
$this->params = [
'queue_id' => '',
'last_event_id' => '',
'dont_block' => '',
];
foreach ($parameters as $key => $val) {
$this->params[$key] = $val;
}
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
use GuzzleHttp\ClientInterface;
use IpSupply\ChatMessage\Helper\Authentication;
class GetEventsRequest extends RequestAbstract
{
use SimpleValidationTrait;
/**
* @var ClientInterface
*/
protected $httpClient;
/**
* @inheritDoc
*/
public function __construct(ClientInterface $client)
{
$this->httpClient = $client;
}
/**
* @inheritDoc
*/
public function initialize($serverUrl, ParametersInterface $params, Authentication $defaultAuthentication)
{
$this->validate($params, ['queue_id', 'last_event_id']);
$auth = $params->getAuthentication();
if (empty($auth)) {
$auth = $defaultAuthentication;
}
$response = $this->httpClient->request('POST',
$serverUrl . '/api/v1/events',
[
'auth' => [
$auth->getUsername(),
$auth->getApiKey(),
],
'form_params' => $params->getData()
]
);
return GetEventsResponse::fromHttpResponse($response);
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
use Psr\Http\Message\ResponseInterface as PsrHttpResponseInterface;
class GetEventsResponse implements ResponseInterface
{
/**
* @var array
*/
private $events;
/**
* @var string
*/
private $result;
public function __construct($events, $result)
{
$this->events = $events;
$this->result = $result;
}
public function isSuccessful()
{
return $this->getResult() == self::RESULT_SUCCESSFUL;
}
/**
* @return array
*/
public function getEvents()
{
return $this->events;
}
/**
* @return string
*/
public function getResult()
{
return $this->result;
}
public static function fromHttpResponse(PsrHttpResponseInterface $response)
{
$body = (string)$response->getBody();
$data = json_decode($body, true);
return new static($data['events'], $data['result']);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
/**
* Class MessageParameters
* @package Zulip\Request
* @method string setType() set message type
* @method string setContent() set content for message
* @method string setTo() set to
* @method string setSubject() set message subject
*/
// use IpSupply\ChatMessage\Helper\Request\SimpleParamTrait;
class MessageParameters extends ParametersAbstract
{
const TYPE_PRIVATE = 'private';
const TYPE_STREAM = 'stream';
use SimpleParamTrait;
/**
* @inheritDoc
*/
public function __construct(array $params = [])
{
$this->params = [
'type' => '',
'content' => '',
'to' => '',
'subject' => ''
];
foreach ($params as $key => $param) {
if (array_key_exists($key, $this->params)) {
$this->params[$key] = $param;
}
}
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
use GuzzleHttp\ClientInterface;
use IpSupply\ChatMessage\Helper\Authentication;
class MessageRequest extends RequestAbstract
{
use SimpleValidationTrait;
/**
* @var ClientInterface
*/
private $client;
public function __construct(ClientInterface $client)
{
$this->client = $client;
}
public function initialize($serverUrl, ParametersInterface $params, Authentication $defaultAuthentication)
{
$this->validate($params, ['type', 'to', 'subject', 'content']);
$auth = $params->getAuthentication();
if (empty($auth)) {
$auth = $defaultAuthentication;
}
$response = $this->client->request('POST',
$serverUrl . '/api/v1/messages',
[
'auth' => [
$auth->getUsername(),
$auth->getApiKey(),
],
'form_params' => $params->getData()
]
);
return MessageResponse::fromHttpResponse($response);
}
}

View File

@ -0,0 +1,92 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
use Psr\Http\Message\ResponseInterface as PsrHttpResponseInterface;
class MessageResponse implements ResponseInterface
{
/**
* @var string
*/
protected $msg;
/**
* @var string
*/
protected $result;
/**
* @var string
*/
protected $id;
/**
* @param string $msg
* @param string $result
* @param string $id
*/
public function __construct($msg, $result, $id)
{
$this->setMsg($msg);
$this->setId($id);
$this->setResult($result);
}
public function isSuccessful()
{
return $this->getMsg() == 'success';
}
/**
* @return string
*/
public function getMsg()
{
return $this->msg;
}
/**
* @param string $msg
*/
public function setMsg($msg)
{
$this->msg = $msg;
}
/**
* @return string
*/
public function getResult()
{
return $this->result;
}
/**
* @param string $result
*/
public function setResult($result)
{
$this->result = $result;
}
/**
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* @param string $id
*/
public function setId($id)
{
$this->id = $id;
}
public static function fromHttpResponse(PsrHttpResponseInterface $response)
{
$body = (string)$response->getBody();
$data = json_decode($body, true);
return new static($data['msg'], $data['result'], $data['id']);
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
use IpSupply\ChatMessage\Helper\Request\ValidationException;
class MissingFieldsValidationException extends ValidationException
{
}

View File

@ -0,0 +1,28 @@
<?php
namespace IpSupply\ChatMessage\Helper\Request;
use IpSupply\ChatMessage\Helper\Authentication;
abstract class ParametersAbstract implements ParametersInterface
{
/**
* @var Authentication;
*/
protected $authentication;
/**
* @inheritDoc
*/
public function setAuthentication(Authentication $authentication)
{
$this->authentication = $authentication;
}
/**
* @inheritDoc
*/
public function getAuthentication()
{
return $this->authentication;
}
}

Some files were not shown because too many files have changed in this diff Show More