├── .gitignore ├── Api ├── CustomFieldsGuestRepositoryInterface.php ├── CustomFieldsRepositoryInterface.php └── Data │ └── CustomFieldsInterface.php ├── Block └── Order │ └── CustomFields.php ├── LICENSE ├── Model ├── CustomFieldsGuestRepository.php ├── CustomFieldsRepository.php └── Data │ └── CustomFields.php ├── Observer └── AddCustomFieldsToOrder.php ├── Plugin └── Block │ └── Adminhtml │ └── CustomFields.php ├── README.md ├── Setup ├── InstallData.php └── Uninstall.php ├── composer.json ├── docs ├── backend_order_custom_information.png ├── frontend_customer_account_orders.png ├── frontened_checkout_custom_form_guest.png └── frontened_checkout_custom_form_logged.png ├── etc ├── adminhtml │ └── di.xml ├── di.xml ├── events.xml ├── module.xml └── webapi.xml ├── i18n └── en_US.csv ├── registration.php └── view ├── adminhtml ├── layout │ └── sales_order_view.xml └── templates │ └── order │ └── view │ └── custom_fields.phtml └── frontend ├── layout ├── checkout_index_index.xml └── sales_order_view.xml ├── requirejs-config.js ├── templates └── order │ └── view │ └── custom_fields.phtml └── web ├── js ├── model │ └── checkout │ │ └── custom-checkout-form.js └── view │ ├── checkout │ └── custom-checkout-form.js │ └── shipping-mixin.js └── template ├── checkout └── custom-checkout-form.html └── shipping.html /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /Api/CustomFieldsGuestRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright © 2017 Slawomir Bodak 8 | * @license See LICENSE file for license details. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace Bodak\CheckoutCustomForm\Api; 14 | 15 | use Magento\Sales\Model\Order; 16 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 17 | 18 | /** 19 | * Interface CustomFieldsGuestRepositoryInterface 20 | * 21 | * @category Api/Interface 22 | * @package Bodak\CheckoutCustomForm\Api 23 | */ 24 | interface CustomFieldsGuestRepositoryInterface 25 | { 26 | /** 27 | * Save checkout custom fields 28 | * 29 | * @param string $cartId Guest Cart id 30 | * @param \Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface $customFields Custom fields 31 | * 32 | * @return \Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface 33 | */ 34 | public function saveCustomFields( 35 | string $cartId, 36 | CustomFieldsInterface $customFields 37 | ): CustomFieldsInterface; 38 | } 39 | -------------------------------------------------------------------------------- /Api/CustomFieldsRepositoryInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright © 2017 Slawomir Bodak 8 | * @license See LICENSE file for license details. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace Bodak\CheckoutCustomForm\Api; 14 | 15 | use Magento\Sales\Model\Order; 16 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 17 | 18 | /** 19 | * Interface CustomFieldsRepositoryInterface 20 | * 21 | * @category Api/Interface 22 | * @package Bodak\CheckoutCustomForm\Api 23 | */ 24 | interface CustomFieldsRepositoryInterface 25 | { 26 | /** 27 | * Save checkout custom fields 28 | * 29 | * @param int $cartId Cart id 30 | * @param \Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface $customFields Custom fields 31 | * 32 | * @return \Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface 33 | */ 34 | public function saveCustomFields( 35 | int $cartId, 36 | CustomFieldsInterface $customFields 37 | ): CustomFieldsInterface; 38 | 39 | /** 40 | * Get checkoug custom fields 41 | * 42 | * @param Order $order Order 43 | * 44 | * @return CustomFieldsInterface 45 | */ 46 | public function getCustomFields(Order $order) : CustomFieldsInterface; 47 | } 48 | -------------------------------------------------------------------------------- /Api/Data/CustomFieldsInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright © 2017 Slawomir Bodak 8 | * @license See LICENSE file for license details. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace Bodak\CheckoutCustomForm\Api\Data; 14 | 15 | /** 16 | * Interface CustomFieldsInterface 17 | * 18 | * @category Api/Data/Interface 19 | * @package Bodak\CheckoutCustomForm\Api\Data 20 | */ 21 | interface CustomFieldsInterface 22 | { 23 | const CHECKOUT_BUYER_NAME = 'checkout_buyer_name'; 24 | const CHECKOUT_BUYER_EMAIL = 'checkout_buyer_email'; 25 | const CHECKOUT_PURCHASE_ORDER_NO = 'checkout_purchase_order_no'; 26 | const CHECKOUT_GOODS_MARK = 'checkout_goods_mark'; 27 | const CHECKOUT_COMMENT = 'checkout_comment'; 28 | 29 | /** 30 | * Get checkout buyer name 31 | * 32 | * @return string|null 33 | */ 34 | public function getCheckoutBuyerName(); 35 | 36 | /** 37 | * Get checkout buyer email 38 | * 39 | * @return string|null 40 | */ 41 | public function getCheckoutBuyerEmail(); 42 | 43 | /** 44 | * Get checkout purchase order number 45 | * 46 | * @return string|null 47 | */ 48 | public function getCheckoutPurchaseOrderNo(); 49 | 50 | /** 51 | * Get checkout goods mark 52 | * 53 | * @return string|null 54 | */ 55 | public function getCheckoutGoodsMark(); 56 | 57 | /** 58 | * Get checkout comment 59 | * 60 | * @return string|null 61 | */ 62 | public function getCheckoutComment(); 63 | 64 | /** 65 | * Set checkout buyer name 66 | * 67 | * @param string|null $checkoutBuyerName Buyer name 68 | * 69 | * @return CustomFieldsInterface 70 | */ 71 | public function setCheckoutBuyerName(string $checkoutBuyerName = null); 72 | 73 | /** 74 | * Set checkout buyer email 75 | * 76 | * @param string|null $checkoutBuyerEmail Buyer email 77 | * 78 | * @return CustomFieldsInterface 79 | */ 80 | public function setCheckoutBuyerEmail(string $checkoutBuyerEmail = null); 81 | 82 | /** 83 | * Set checkout purchase order number 84 | * 85 | * @param string|null $checkoutPurchaseOrderNo Purchase order number 86 | * 87 | * @return CustomFieldsInterface 88 | */ 89 | public function setCheckoutPurchaseOrderNo(string $checkoutPurchaseOrderNo = null); 90 | 91 | /** 92 | * Set checkout goods mark 93 | * 94 | * @param string|null $checkoutGoodsMark Goods mark 95 | * 96 | * @return CustomFieldsInterface 97 | */ 98 | public function setCheckoutGoodsMark(string $checkoutGoodsMark = null); 99 | 100 | /** 101 | * Set checkout comment 102 | * 103 | * @param string|null $comment Comment 104 | * 105 | * @return CustomFieldsInterface 106 | */ 107 | public function setCheckoutComment(string $comment = null); 108 | } 109 | -------------------------------------------------------------------------------- /Block/Order/CustomFields.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright © 2017 Slawomir Bodak 8 | * @license See LICENSE file for license details. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace Bodak\CheckoutCustomForm\Block\Order; 14 | 15 | use Magento\Framework\View\Element\Template; 16 | use Magento\Framework\View\Element\Template\Context; 17 | use Magento\Framework\Registry; 18 | use Magento\Sales\Model\Order; 19 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 20 | use Bodak\CheckoutCustomForm\Api\CustomFieldsRepositoryInterface; 21 | 22 | /** 23 | * Class CustomFields 24 | * 25 | * @category Block/Order 26 | * @package Bodak\CheckoutCustomForm\Block 27 | */ 28 | class CustomFields extends Template 29 | { 30 | /** 31 | * Core registry 32 | * 33 | * @var Registry 34 | */ 35 | protected $coreRegistry = null; 36 | 37 | /** 38 | * CustomFieldsRepositoryInterface 39 | * 40 | * @var CustomFieldsRepositoryInterface 41 | */ 42 | protected $customFieldsRepository; 43 | 44 | /** 45 | * CustomFields constructor. 46 | * 47 | * @param Context $context Context 48 | * @param Registry $registry Registry 49 | * @param CustomFieldsRepositoryInterface $customFieldsRepository CustomFieldsRepositoryInterface 50 | * @param array $data Data 51 | */ 52 | public function __construct( 53 | Context $context, 54 | Registry $registry, 55 | CustomFieldsRepositoryInterface $customFieldsRepository, 56 | array $data = [] 57 | ) { 58 | $this->coreRegistry = $registry; 59 | $this->customFieldsRepository = $customFieldsRepository; 60 | $this->_isScopePrivate = true; 61 | $this->_template = 'order/view/custom_fields.phtml'; 62 | parent::__construct($context, $data); 63 | } 64 | 65 | /** 66 | * Get current order 67 | * 68 | * @return Order 69 | */ 70 | public function getOrder() : Order 71 | { 72 | return $this->coreRegistry->registry('current_order'); 73 | } 74 | 75 | /** 76 | * Get checkout custom fields 77 | * 78 | * @param Order $order Order 79 | * 80 | * @return CustomFieldsInterface 81 | */ 82 | public function getCustomFields(Order $order) 83 | { 84 | return $this->customFieldsRepository->getCustomFields($order); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Slawomir Bodak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Model/CustomFieldsGuestRepository.php: -------------------------------------------------------------------------------- 1 | 5 | * @copyright © 2017 Slawomir Bodak 6 | * @license See LICENSE file for license details. 7 | */ 8 | 9 | declare(strict_types=1); 10 | 11 | namespace Bodak\CheckoutCustomForm\Model; 12 | 13 | use Magento\Quote\Model\QuoteIdMaskFactory; 14 | use Bodak\CheckoutCustomForm\Api\CustomFieldsGuestRepositoryInterface; 15 | use Bodak\CheckoutCustomForm\Api\CustomFieldsRepositoryInterface; 16 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 17 | 18 | /** 19 | * Class CustomFieldsGuestRepository 20 | * 21 | * @category Model/Repository 22 | * @package Bodak\CheckoutCustomForm\Model 23 | */ 24 | class CustomFieldsGuestRepository implements CustomFieldsGuestRepositoryInterface 25 | { 26 | /** 27 | * @var QuoteIdMaskFactory 28 | */ 29 | protected $quoteIdMaskFactory; 30 | 31 | /** 32 | * @var CustomFieldsRepositoryInterface 33 | */ 34 | protected $customFieldsRepository; 35 | 36 | /** 37 | * @param QuoteIdMaskFactory $quoteIdMaskFactory 38 | * @param CustomFieldsRepositoryInterface $customFieldsRepository 39 | */ 40 | public function __construct( 41 | QuoteIdMaskFactory $quoteIdMaskFactory, 42 | CustomFieldsRepositoryInterface $customFieldsRepository 43 | ) { 44 | $this->quoteIdMaskFactory = $quoteIdMaskFactory; 45 | $this->customFieldsRepository = $customFieldsRepository; 46 | } 47 | 48 | /** 49 | * @param string $cartId 50 | * @param CustomFieldsInterface $customFields 51 | * @return CustomFieldsInterface 52 | */ 53 | public function saveCustomFields( 54 | string $cartId, 55 | CustomFieldsInterface $customFields 56 | ): CustomFieldsInterface { 57 | $quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id'); 58 | return $this->customFieldsRepository->saveCustomFields((int)$quoteIdMask->getQuoteId(), $customFields); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Model/CustomFieldsRepository.php: -------------------------------------------------------------------------------- 1 | 5 | * @copyright © 2017 Slawomir Bodak 6 | * @license See LICENSE file for license details. 7 | */ 8 | 9 | declare(strict_types=1); 10 | 11 | namespace Bodak\CheckoutCustomForm\Model; 12 | 13 | use Magento\Quote\Api\CartRepositoryInterface; 14 | use Magento\Framework\App\Config\ScopeConfigInterface; 15 | use Magento\Framework\Exception\NoSuchEntityException; 16 | use Magento\Framework\Exception\CouldNotSaveException; 17 | use Magento\Sales\Model\Order; 18 | use Bodak\CheckoutCustomForm\Api\CustomFieldsRepositoryInterface; 19 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 20 | 21 | /** 22 | * Class CustomFieldsRepository 23 | * 24 | * @category Model/Repository 25 | * @package Bodak\CheckoutCustomForm\Model 26 | */ 27 | class CustomFieldsRepository implements CustomFieldsRepositoryInterface 28 | { 29 | /** 30 | * Quote repository. 31 | * 32 | * @var CartRepositoryInterface 33 | */ 34 | protected $cartRepository; 35 | 36 | /** 37 | * ScopeConfigInterface 38 | * 39 | * @var ScopeConfigInterface 40 | */ 41 | protected $scopeConfig; 42 | 43 | /** 44 | * CustomFieldsInterface 45 | * 46 | * @var CustomFieldsInterface 47 | */ 48 | protected $customFields; 49 | 50 | /** 51 | * CustomFieldsRepository constructor. 52 | * 53 | * @param CartRepositoryInterface $cartRepository CartRepositoryInterface 54 | * @param ScopeConfigInterface $scopeConfig ScopeConfigInterface 55 | * @param CustomFieldsInterface $customFields CustomFieldsInterface 56 | */ 57 | public function __construct( 58 | CartRepositoryInterface $cartRepository, 59 | ScopeConfigInterface $scopeConfig, 60 | CustomFieldsInterface $customFields 61 | ) { 62 | $this->cartRepository = $cartRepository; 63 | $this->scopeConfig = $scopeConfig; 64 | $this->customFields = $customFields; 65 | } 66 | /** 67 | * Save checkout custom fields 68 | * 69 | * @param int $cartId Cart id 70 | * @param \Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface $customFields Custom fields 71 | * 72 | * @return \Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface 73 | * @throws CouldNotSaveException 74 | * @throws NoSuchEntityException 75 | */ 76 | public function saveCustomFields( 77 | int $cartId, 78 | CustomFieldsInterface $customFields 79 | ): CustomFieldsInterface { 80 | $cart = $this->cartRepository->getActive($cartId); 81 | if (!$cart->getItemsCount()) { 82 | throw new NoSuchEntityException(__('Cart %1 is empty', $cartId)); 83 | } 84 | 85 | try { 86 | $cart->setData( 87 | CustomFieldsInterface::CHECKOUT_BUYER_NAME, 88 | $customFields->getCheckoutBuyerName() 89 | ); 90 | $cart->setData( 91 | CustomFieldsInterface::CHECKOUT_BUYER_EMAIL, 92 | $customFields->getCheckoutBuyerEmail() 93 | ); 94 | $cart->setData( 95 | CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO, 96 | $customFields->getCheckoutPurchaseOrderNo() 97 | ); 98 | $cart->setData( 99 | CustomFieldsInterface::CHECKOUT_GOODS_MARK, 100 | $customFields->getCheckoutGoodsMark() 101 | ); 102 | $cart->setData( 103 | CustomFieldsInterface::CHECKOUT_COMMENT, 104 | $customFields->getCheckoutComment() 105 | ); 106 | 107 | $this->cartRepository->save($cart); 108 | } catch (\Exception $e) { 109 | throw new CouldNotSaveException(__('Custom order data could not be saved!')); 110 | } 111 | 112 | return $customFields; 113 | } 114 | 115 | /** 116 | * Get checkout custom fields by given order id 117 | * 118 | * @param Order $order Order 119 | * 120 | * @return CustomFieldsInterface 121 | * @throws NoSuchEntityException 122 | */ 123 | public function getCustomFields(Order $order): CustomFieldsInterface 124 | { 125 | if (!$order->getId()) { 126 | throw new NoSuchEntityException(__('Order %1 does not exist', $order)); 127 | } 128 | 129 | $this->customFields->setCheckoutBuyerName( 130 | $order->getData(CustomFieldsInterface::CHECKOUT_BUYER_NAME) 131 | ); 132 | $this->customFields->setCheckoutBuyerEmail( 133 | $order->getData(CustomFieldsInterface::CHECKOUT_BUYER_EMAIL) 134 | ); 135 | $this->customFields->setCheckoutPurchaseOrderNo( 136 | $order->getData(CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO) 137 | ); 138 | $this->customFields->setCheckoutGoodsMark( 139 | $order->getData(CustomFieldsInterface::CHECKOUT_GOODS_MARK) 140 | ); 141 | $this->customFields->setCheckoutComment( 142 | $order->getData(CustomFieldsInterface::CHECKOUT_COMMENT) 143 | ); 144 | 145 | return $this->customFields; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Model/Data/CustomFields.php: -------------------------------------------------------------------------------- 1 | 5 | * @copyright © 2017 Slawomir Bodak 6 | * @license See LICENSE file for license details. 7 | */ 8 | 9 | declare(strict_types=1); 10 | 11 | namespace Bodak\CheckoutCustomForm\Model\Data; 12 | 13 | use Magento\Framework\Api\AbstractExtensibleObject; 14 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 15 | 16 | /** 17 | * Class CustomFields 18 | * 19 | * @category Model/Data 20 | * @package Bodak\CheckoutCustomForm\Model\Data 21 | */ 22 | class CustomFields extends AbstractExtensibleObject implements CustomFieldsInterface 23 | { 24 | /** 25 | * Get checkout buyer name 26 | * 27 | * @return string|null 28 | */ 29 | public function getCheckoutBuyerName() 30 | { 31 | return $this->_get(self::CHECKOUT_BUYER_NAME); 32 | } 33 | 34 | /** 35 | * Get checkout buyer email 36 | * 37 | * @return string|null 38 | */ 39 | public function getCheckoutBuyerEmail() 40 | { 41 | return $this->_get(self::CHECKOUT_BUYER_EMAIL); 42 | } 43 | 44 | /** 45 | * Get checkout purchase order number 46 | * 47 | * @return string|null 48 | */ 49 | public function getCheckoutPurchaseOrderNo() 50 | { 51 | return $this->_get(self::CHECKOUT_PURCHASE_ORDER_NO); 52 | } 53 | 54 | /** 55 | * Get checkout goods mark 56 | * 57 | * @return string|null 58 | */ 59 | public function getCheckoutGoodsMark() 60 | { 61 | return $this->_get(self::CHECKOUT_GOODS_MARK); 62 | } 63 | 64 | /** 65 | * Get checkout comment 66 | * 67 | * @return string|null 68 | */ 69 | public function getCheckoutComment() 70 | { 71 | return $this->_get(self::CHECKOUT_COMMENT); 72 | } 73 | 74 | /** 75 | * Set checkout buyer name 76 | * 77 | * @param string|null $checkoutBuyerName Buyer name 78 | * 79 | * @return CustomFieldsInterface 80 | */ 81 | public function setCheckoutBuyerName(string $checkoutBuyerName = null) 82 | { 83 | return $this->setData(self::CHECKOUT_BUYER_NAME, $checkoutBuyerName); 84 | } 85 | 86 | /** 87 | * Set checkout buyer email 88 | * 89 | * @param string|null $checkoutBuyerEmail Buyer email 90 | * 91 | * @return CustomFieldsInterface 92 | */ 93 | public function setCheckoutBuyerEmail(string $checkoutBuyerEmail = null) 94 | { 95 | return $this->setData(self::CHECKOUT_BUYER_EMAIL, $checkoutBuyerEmail); 96 | } 97 | 98 | /** 99 | * Set checkout purchase order number 100 | * 101 | * @param string|null $checkoutPurchaseOrderNo Purchase order number 102 | * 103 | * @return CustomFieldsInterface 104 | */ 105 | public function setCheckoutPurchaseOrderNo(string $checkoutPurchaseOrderNo = null) 106 | { 107 | return $this->setData(self::CHECKOUT_PURCHASE_ORDER_NO, $checkoutPurchaseOrderNo); 108 | } 109 | 110 | /** 111 | * Set checkout goods mark 112 | * 113 | * @param string|null $checkoutGoodsMark Goods mark 114 | * 115 | * @return CustomFieldsInterface 116 | */ 117 | public function setCheckoutGoodsMark(string $checkoutGoodsMark = null) 118 | { 119 | return $this->setData(self::CHECKOUT_GOODS_MARK, $checkoutGoodsMark); 120 | } 121 | 122 | /** 123 | * Set checkout comment 124 | * 125 | * @param string|null $comment Comment 126 | * 127 | * @return CustomFieldsInterface 128 | */ 129 | public function setCheckoutComment(string $comment = null) 130 | { 131 | return $this->setData(self::CHECKOUT_COMMENT, $comment); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /Observer/AddCustomFieldsToOrder.php: -------------------------------------------------------------------------------- 1 | 5 | * @copyright © 2017 Slawomir Bodak 6 | * @license See LICENSE file for license details. 7 | */ 8 | 9 | declare(strict_types=1); 10 | 11 | namespace Bodak\CheckoutCustomForm\Observer; 12 | 13 | use Magento\Framework\Event\ObserverInterface; 14 | use Magento\Framework\Event\Observer; 15 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 16 | 17 | /** 18 | * Class AddCustomFieldsToOrder 19 | * 20 | * @category Observer 21 | * @package Bodak\CheckoutCustomForm\Observer 22 | */ 23 | class AddCustomFieldsToOrder implements ObserverInterface 24 | { 25 | /** 26 | * Execute observer method. 27 | * 28 | * @param Observer $observer Observer 29 | * 30 | * @return void 31 | */ 32 | public function execute(Observer $observer) 33 | { 34 | $order = $observer->getEvent()->getOrder(); 35 | $quote = $observer->getEvent()->getQuote(); 36 | 37 | $order->setData( 38 | CustomFieldsInterface::CHECKOUT_BUYER_NAME, 39 | $quote->getData(CustomFieldsInterface::CHECKOUT_BUYER_NAME) 40 | ); 41 | $order->setData( 42 | CustomFieldsInterface::CHECKOUT_BUYER_EMAIL, 43 | $quote->getData(CustomFieldsInterface::CHECKOUT_BUYER_EMAIL) 44 | ); 45 | $order->setData( 46 | CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO, 47 | $quote->getData(CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO) 48 | ); 49 | $order->setData( 50 | CustomFieldsInterface::CHECKOUT_GOODS_MARK, 51 | $quote->getData(CustomFieldsInterface::CHECKOUT_GOODS_MARK) 52 | ); 53 | $order->setData( 54 | CustomFieldsInterface::CHECKOUT_COMMENT, 55 | $quote->getData(CustomFieldsInterface::CHECKOUT_COMMENT) 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Plugin/Block/Adminhtml/CustomFields.php: -------------------------------------------------------------------------------- 1 | 5 | * @copyright © 2017 Slawomir Bodak 6 | * @license See LICENSE file for license details. 7 | */ 8 | 9 | declare(strict_types=1); 10 | 11 | namespace Bodak\CheckoutCustomForm\Plugin\Block\Adminhtml; 12 | 13 | use Magento\Framework\Exception\LocalizedException; 14 | use Magento\Sales\Block\Adminhtml\Order\View\Info; 15 | use Bodak\CheckoutCustomForm\Api\CustomFieldsRepositoryInterface; 16 | 17 | /** 18 | * Class CustomFieldsRepository 19 | * 20 | * @category Adminhtml/Plugin 21 | * @package Bodak\CheckoutCustomForm\Plugin 22 | */ 23 | class CustomFields 24 | { 25 | /** 26 | * CustomFieldsRepositoryInterface 27 | * 28 | * @var CustomFieldsRepositoryInterface 29 | */ 30 | protected $customFieldsRepository; 31 | 32 | /** 33 | * CustomFields constructor. 34 | * 35 | * @param CustomFieldsRepositoryInterface $customFieldsRepository Repository Interface 36 | */ 37 | public function __construct(CustomFieldsRepositoryInterface $customFieldsRepository) 38 | { 39 | $this->customFieldsRepository = $customFieldsRepository; 40 | } 41 | 42 | /** 43 | * Modify after to html. 44 | * 45 | * @param Info $subject Info 46 | * @param string $result Result 47 | * 48 | * @return string 49 | * @throws LocalizedException 50 | */ 51 | public function afterToHtml(Info $subject, $result) { 52 | $block = $subject->getLayout()->getBlock('order_custom_fields'); 53 | if ($block !== false) { 54 | $block->setOrderCustomFields( 55 | $this->customFieldsRepository->getCustomFields($subject->getOrder()) 56 | ); 57 | $result = $result . $block->toHtml(); 58 | } 59 | 60 | return $result; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Magento 2 - Checkout custom form 2 | 3 | ## Overview 4 | Add a custom form fields to the Magento 2 checkout. The form will appear in the first checkout step (shipping step) above shipping methods. 5 | The form is available for logged in customers and guests. After an order is placed all data are set in `sales_order` table. 6 | Data are still in the form after page refreshed, till cart is active. 7 | 8 | Form data will be set in a `quota` table through independent API request: 9 | - `/V1/carts/mine/set-order-custom-fields` (for logged in customer) 10 | - `/V1/guest-carts/:cartId/set-order-custom-field` (for guest) 11 | 12 | ## Compatibility 13 | - Tag 1.2.* => Magento 2.3 14 | - Tag 1.1.* => Magento 2.1.x - 2.2.x (no longer supported) 15 | 16 | ## Requirements 17 | - PHP 7.0 or higher 18 | 19 | ## Installation details 20 | 1. Run `composer require sbodak/magento2-checkout-custom-form` 21 | 2. Run `php bin/magento module:enable Bodak_CheckoutCustomForm` 22 | 3. Run `php bin/magento setup:upgrade` 23 | 24 | ### Sample custom form fields 25 | - buyer 26 | - buyer email address 27 | - purchase order no. 28 | - goods mark 29 | - comments 30 | 31 | ### Modify form fields 32 | - You need to modify service contract data interface in `Api/Data/CustomFieldsInterfaces.php` 33 | - You need to modify table schema in `Setup/InstallData.php` 34 | - You need to add new fields to observer `Observer/AddCustomFieldsToOrder.php` which save data in quota and sales table 35 | - You need to add new item in `view/frontend/layout/checkout_index_index.xml` 36 | - You need to modify the methods in `Model/Data/CustomFields.php` 37 | - You need to modify the methods in `Model/CustomFieldsRepository.php` 38 | 39 | ``` 40 | 41 | uiComponent 42 | custom-checkout-form-fields 43 | 44 | [... place here new definition of your field] 45 | 46 | 47 | ``` 48 | 49 | Check official documentation: https://devdocs.magento.com/guides/v2.3/howdoi/checkout/checkout_form.html 50 | 51 | - You need to modify template views in `view/frontend/templates/order/view/custom_fields.phtml` (for customer account) 52 | and `view/adminhtml/templates/order/view/custom_fields.phtml (for admin panel)`. 53 | - Checkout form view is generated automatically using Ui Components 54 | 55 | ### Required entry 56 | If you want to make field required, check this example: 57 | ``` 58 | 59 | Magento_Ui/js/form/element/abstract 60 | 61 | customCheckoutForm 62 | ui/form/field 63 | ui/form/element/input 64 | 65 | 66 | true 67 | 68 | checkoutProvider 69 | customCheckoutForm.checkout_purchase_order_no 70 | Purchase order no. 71 | 3 72 | 73 | ``` 74 | 75 | ### Fast fields override 76 | You can modify `i18n/en_US.csv` translation to change field names. 77 | 78 | ### Checkout view - custom form - Guest 79 | ![Checkout frontend custom form - Guest](docs/frontened_checkout_custom_form_guest.png) 80 | 81 | ### Checkout view - custom form - Logged in 82 | ![Checkout frontend custom form - Logged in](docs/frontened_checkout_custom_form_logged.png) 83 | 84 | ### Custom account - Order history view 85 | ![Customer account - Order history view](docs/frontend_customer_account_orders.png) 86 | 87 | ### Admin panel - Order Edit 88 | ![Admin panel - order edit](docs/backend_order_custom_information.png) 89 | 90 | 91 | ## Uninstall 92 | To remove this module run `php bin/magento module:uninstall Bodak_CheckoutCustomForm`. 93 | It will remove all data and drop columns in `sales_order` and `quote` tables. 94 | 95 | ## License 96 | [MIT License](LICENSE) -------------------------------------------------------------------------------- /Setup/InstallData.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright © 2017 Slawomir Bodak 8 | * @license See LICENSE file for license details. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace Bodak\CheckoutCustomForm\Setup; 14 | 15 | use Magento\Framework\Setup\InstallDataInterface; 16 | use Magento\Framework\Setup\ModuleContextInterface; 17 | use Magento\Framework\Setup\ModuleDataSetupInterface; 18 | use Magento\Quote\Setup\QuoteSetupFactory; 19 | use Magento\Sales\Setup\SalesSetupFactory; 20 | use Magento\Framework\DB\Ddl\Table; 21 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 22 | 23 | /** 24 | * Class InstallData 25 | * 26 | * @category InstallData 27 | * @package Bodak\CheckoutCustomForm\Setup 28 | */ 29 | class InstallData implements InstallDataInterface 30 | { 31 | /** 32 | * SalesSetupFactory 33 | * 34 | * @var SalesSetupFactory 35 | */ 36 | protected $salesSetupFactory; 37 | 38 | /** 39 | * QuoteSetupFactory 40 | * 41 | * @var QuoteSetupFactory 42 | */ 43 | protected $quoteSetupFactory; 44 | 45 | /** 46 | * ModuleDataSetupInterface 47 | * 48 | * @var ModuleDataSetupInterface 49 | */ 50 | protected $setup; 51 | 52 | /** 53 | * InstallData constructor. 54 | * 55 | * @param SalesSetupFactory $salesSetupFactory SalesSetupFactory 56 | * @param QuoteSetupFactory $quoteSetupFactory QuoteSetupFactory 57 | */ 58 | public function __construct( 59 | SalesSetupFactory $salesSetupFactory, 60 | QuoteSetupFactory $quoteSetupFactory 61 | ) { 62 | $this->salesSetupFactory = $salesSetupFactory; 63 | $this->quoteSetupFactory = $quoteSetupFactory; 64 | } 65 | 66 | /** 67 | * Install data 68 | * 69 | * @param ModuleDataSetupInterface $setup ModuleDataSetupInterface 70 | * @param ModuleContextInterface $context ModuleContextInterface 71 | * 72 | * @return void 73 | */ 74 | public function install( 75 | ModuleDataSetupInterface $setup, 76 | ModuleContextInterface $context 77 | ) { 78 | $this->setup = $setup->startSetup(); 79 | $this->installQuoteData(); 80 | $this->installSalesData(); 81 | $this->setup = $setup->endSetup(); 82 | } 83 | 84 | /** 85 | * Install quote custom data 86 | * 87 | * @return void 88 | */ 89 | public function installQuoteData() 90 | { 91 | $quoteInstaller = $this->quoteSetupFactory->create( 92 | [ 93 | 'resourceName' => 'quote_setup', 94 | 'setup' => $this->setup 95 | ] 96 | ); 97 | $quoteInstaller 98 | ->addAttribute( 99 | 'quote', 100 | CustomFieldsInterface::CHECKOUT_BUYER_NAME, 101 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true] 102 | ) 103 | ->addAttribute( 104 | 'quote', 105 | CustomFieldsInterface::CHECKOUT_BUYER_EMAIL, 106 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true] 107 | ) 108 | ->addAttribute( 109 | 'quote', 110 | CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO, 111 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true] 112 | ) 113 | ->addAttribute( 114 | 'quote', 115 | CustomFieldsInterface::CHECKOUT_GOODS_MARK, 116 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true] 117 | ) 118 | ->addAttribute( 119 | 'quote', 120 | CustomFieldsInterface::CHECKOUT_COMMENT, 121 | ['type' => Table::TYPE_TEXT, 'length' => '64k', 'nullable' => true] 122 | ); 123 | } 124 | 125 | /** 126 | * Install sales custom data 127 | * 128 | * @return void 129 | */ 130 | public function installSalesData() 131 | { 132 | $salesInstaller = $this->salesSetupFactory->create( 133 | [ 134 | 'resourceName' => 'sales_setup', 135 | 'setup' => $this->setup 136 | ] 137 | ); 138 | $salesInstaller 139 | ->addAttribute( 140 | 'order', 141 | CustomFieldsInterface::CHECKOUT_BUYER_NAME, 142 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true, 'grid' => false] 143 | ) 144 | ->addAttribute( 145 | 'order', 146 | CustomFieldsInterface::CHECKOUT_BUYER_EMAIL, 147 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true, 'grid' => false] 148 | ) 149 | ->addAttribute( 150 | 'order', 151 | CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO, 152 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true, 'grid' => false] 153 | ) 154 | ->addAttribute( 155 | 'order', 156 | CustomFieldsInterface::CHECKOUT_GOODS_MARK, 157 | ['type' => Table::TYPE_TEXT, 'length' => '255', 'nullable' => true, 'grid' => false] 158 | ) 159 | ->addAttribute( 160 | 'order', 161 | CustomFieldsInterface::CHECKOUT_COMMENT, 162 | ['type' => Table::TYPE_TEXT, 'length' => '64k', 'nullable' => true, 'grid' => false] 163 | ); 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /Setup/Uninstall.php: -------------------------------------------------------------------------------- 1 | 7 | * @copyright © 2017 Slawomir Bodak 8 | * @license See LICENSE file for license details. 9 | */ 10 | 11 | declare(strict_types=1); 12 | 13 | namespace Bodak\CheckoutCustomForm\Setup; 14 | 15 | use Magento\Framework\Setup\ModuleContextInterface; 16 | use Magento\Framework\Setup\SchemaSetupInterface; 17 | use Magento\Framework\Setup\UninstallInterface; 18 | use Bodak\CheckoutCustomForm\Api\Data\CustomFieldsInterface; 19 | 20 | /** 21 | * Class Uninstall 22 | * 23 | * @category Uninstall 24 | * @package Bodak\CheckoutCustomForm\Setup 25 | */ 26 | class Uninstall implements UninstallInterface 27 | { 28 | /** 29 | * SchemaSetupInterface 30 | * 31 | * @var SchemaSetupInterface 32 | */ 33 | protected $setup; 34 | 35 | /** 36 | * Uninstall data 37 | * 38 | * @param SchemaSetupInterface $setup SchemaSetupInterface 39 | * @param ModuleContextInterface $context ModuleContextInterface 40 | * 41 | * @return void 42 | */ 43 | public function uninstall( 44 | SchemaSetupInterface $setup, 45 | ModuleContextInterface $context 46 | ) { 47 | $this->setup = $setup->startSetup(); 48 | $this->uninstallQuoteData(); 49 | $this->uninstallSalesData(); 50 | $this->setup = $setup->endSetup(); 51 | } 52 | 53 | /** 54 | * Uninstall quote custom data 55 | * 56 | * @return void 57 | */ 58 | public function uninstallQuoteData() 59 | { 60 | $this->setup->getConnection()->dropColumn( 61 | $this->setup->getTable('quote'), 62 | CustomFieldsInterface::CHECKOUT_BUYER_NAME 63 | ); 64 | $this->setup->getConnection()->dropColumn( 65 | $this->setup->getTable('quote'), 66 | CustomFieldsInterface::CHECKOUT_BUYER_EMAIL 67 | ); 68 | $this->setup->getConnection()->dropColumn( 69 | $this->setup->getTable('quote'), 70 | CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO 71 | ); 72 | $this->setup->getConnection()->dropColumn( 73 | $this->setup->getTable('quote'), 74 | CustomFieldsInterface::CHECKOUT_GOODS_MARK 75 | ); 76 | $this->setup->getConnection()->dropColumn( 77 | $this->setup->getTable('quote'), 78 | CustomFieldsInterface::CHECKOUT_COMMENT 79 | ); 80 | } 81 | 82 | /** 83 | * Uninstall sales custom data 84 | * 85 | * @return void 86 | */ 87 | public function uninstallSalesData() 88 | { 89 | $this->setup->getConnection()->dropColumn( 90 | $this->setup->getTable('sales_order'), 91 | CustomFieldsInterface::CHECKOUT_BUYER_NAME 92 | ); 93 | $this->setup->getConnection()->dropColumn( 94 | $this->setup->getTable('sales_order'), 95 | CustomFieldsInterface::CHECKOUT_BUYER_EMAIL 96 | ); 97 | $this->setup->getConnection()->dropColumn( 98 | $this->setup->getTable('sales_order'), 99 | CustomFieldsInterface::CHECKOUT_PURCHASE_ORDER_NO 100 | ); 101 | $this->setup->getConnection()->dropColumn( 102 | $this->setup->getTable('sales_order'), 103 | CustomFieldsInterface::CHECKOUT_GOODS_MARK 104 | ); 105 | $this->setup->getConnection()->dropColumn( 106 | $this->setup->getTable('sales_order'), 107 | CustomFieldsInterface::CHECKOUT_COMMENT 108 | ); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sbodak/magento2-checkout-custom-form", 3 | "description": "Add a custom form to Magento 2 checkout on the first step.", 4 | "license": [ 5 | "MIT" 6 | ], 7 | "type": "magento2-module", 8 | "keywords": ["magento2", "custom checkout"], 9 | "version": "1.2.1", 10 | "authors": [ 11 | { 12 | "name": "Slawomir Bodak", 13 | "email": "slawek.bodak@gmail.com" 14 | } 15 | ], 16 | "require": { 17 | "php": "~7.0.0|~7.1.3|~7.2.0" 18 | }, 19 | "autoload": { 20 | "files": [ 21 | "registration.php" 22 | ], 23 | "psr-4": { 24 | "Bodak\\CheckoutCustomForm\\": "" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/backend_order_custom_information.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbodak/magento2-checkout-custom-form/0b5af544a25984b9c67bb44d3273989e371e2f57/docs/backend_order_custom_information.png -------------------------------------------------------------------------------- /docs/frontend_customer_account_orders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbodak/magento2-checkout-custom-form/0b5af544a25984b9c67bb44d3273989e371e2f57/docs/frontend_customer_account_orders.png -------------------------------------------------------------------------------- /docs/frontened_checkout_custom_form_guest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbodak/magento2-checkout-custom-form/0b5af544a25984b9c67bb44d3273989e371e2f57/docs/frontened_checkout_custom_form_guest.png -------------------------------------------------------------------------------- /docs/frontened_checkout_custom_form_logged.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sbodak/magento2-checkout-custom-form/0b5af544a25984b9c67bb44d3273989e371e2f57/docs/frontened_checkout_custom_form_logged.png -------------------------------------------------------------------------------- /etc/adminhtml/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /etc/di.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /etc/events.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /etc/module.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /etc/webapi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %cart_id% 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /i18n/en_US.csv: -------------------------------------------------------------------------------- 1 | "Other information","Other information" 2 | "Buyer name","Buyer name" 3 | "Buyer email","Buyer email" 4 | "Purchase order no.","Purchase order no." 5 | "Goods mark","Goods mark" 6 | "Comment","Comment" 7 | "* Required Fields","* Required Fields" -------------------------------------------------------------------------------- /registration.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /view/adminhtml/templates/order/view/custom_fields.phtml: -------------------------------------------------------------------------------- 1 | getOrderCustomFields(); 6 | ?> 7 | 8 |
9 |
10 | 11 |
12 |
13 |
14 |
15 | 16 |
17 | escapeHtml($customFields->getCheckoutBuyerName()); ?> 18 |
19 |
20 |
21 | 22 |
23 | escapeHtml($customFields->getCheckoutBuyerEmail()); ?> 24 |
25 |
26 |
27 | 28 |
29 | escapeHtml($customFields->getCheckoutPurchaseOrderNo()); ?> 30 |
31 |
32 |
33 | 34 |
35 | escapeHtml($customFields->getCheckoutGoodsMark()); ?> 36 |
37 |
38 |
39 | 40 |
41 |
42 | 43 |
44 | escapeHtml($customFields->getCheckoutComment())); ?> 45 |
46 |
47 |
48 |
49 |
50 | 51 | -------------------------------------------------------------------------------- /view/frontend/layout/checkout_index_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | uiComponent 18 | custom-checkout-form 19 | 20 | 21 | 0 22 | Bodak_CheckoutCustomForm/js/view/checkout/custom-checkout-form 23 | checkoutProvider 24 | 25 | Bodak_CheckoutCustomForm/checkout/custom-checkout-form 26 | 27 | 28 | 29 | uiComponent 30 | custom-checkout-form-fields 31 | 32 | 33 | Magento_Ui/js/form/element/abstract 34 | 35 | customCheckoutForm 36 | ui/form/field 37 | ui/form/element/input 38 | 39 | checkoutProvider 40 | customCheckoutForm.checkout_buyer_name 41 | Buyer name 42 | 1 43 | 44 | 45 | Magento_Ui/js/form/element/abstract 46 | 47 | customCheckoutForm 48 | ui/form/field 49 | ui/form/element/email 50 | 51 | We will send an order confirmation to this email address 52 | 53 | 54 | checkoutProvider 55 | customCheckoutForm.checkout_buyer_email 56 | Buyer email 57 | 2 58 | 59 | true 60 | 61 | 62 | 63 | Magento_Ui/js/form/element/abstract 64 | 65 | customCheckoutForm 66 | ui/form/field 67 | ui/form/element/input 68 | 69 | 70 | true 71 | 72 | checkoutProvider 73 | customCheckoutForm.checkout_purchase_order_no 74 | Purchase order no. 75 | 3 76 | 77 | 78 | Magento_Ui/js/form/element/abstract 79 | 80 | customCheckoutForm 81 | ui/form/field 82 | ui/form/element/input 83 | 84 | checkoutProvider 85 | customCheckoutForm.checkout_goods_mark 86 | Goods mark 87 | 4 88 | 89 | 90 | Magento_Ui/js/form/element/abstract 91 | 92 | customCheckoutForm 93 | ui/form/field 94 | ui/form/element/textarea 95 | 15 96 | 2 97 | 98 | checkoutProvider 99 | customCheckoutForm.checkout_comment 100 | Comment 101 | 5 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /view/frontend/layout/sales_order_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /view/frontend/requirejs-config.js: -------------------------------------------------------------------------------- 1 | var config = { 2 | config: { 3 | mixins: { 4 | 'Magento_Checkout/js/view/shipping': { 5 | 'Bodak_CheckoutCustomForm/js/view/shipping-mixin': true 6 | } 7 | } 8 | } 9 | }; -------------------------------------------------------------------------------- /view/frontend/templates/order/view/custom_fields.phtml: -------------------------------------------------------------------------------- 1 | getCustomFields($block->getOrder()); 6 | ?> 7 | 8 |
9 |
10 |
11 | 12 |
13 | : 14 | escapeHtml($customFields->getCheckoutBuyerName()); ?>
15 | : 16 | escapeHtml($customFields->getCheckoutBuyerEmail()); ?>
17 | : 18 | escapeHtml($customFields->getCheckoutPurchaseOrderNo()); ?>
19 | : 20 | escapeHtml($customFields->getCheckoutGoodsMark()); ?> 21 |
22 |
23 | 24 |
25 | 26 |
27 | escapeHtml($customFields->getCheckoutComment())); ?> 28 |
29 |
30 |
31 |
32 | 33 | -------------------------------------------------------------------------------- /view/frontend/web/js/model/checkout/custom-checkout-form.js: -------------------------------------------------------------------------------- 1 | define( 2 | [ 3 | 'ko', 4 | ], 5 | function(ko) { 6 | 'use strict'; 7 | return{ 8 | customFieldsData: ko.observable(null) 9 | } 10 | } 11 | ); -------------------------------------------------------------------------------- /view/frontend/web/js/view/checkout/custom-checkout-form.js: -------------------------------------------------------------------------------- 1 | /*global define*/ 2 | define([ 3 | 'knockout', 4 | 'jquery', 5 | 'mage/url', 6 | 'Magento_Ui/js/form/form', 7 | 'Magento_Customer/js/model/customer', 8 | 'Magento_Checkout/js/model/quote', 9 | 'Magento_Checkout/js/model/url-builder', 10 | 'Magento_Checkout/js/model/error-processor', 11 | 'Magento_Checkout/js/model/cart/cache', 12 | 'Bodak_CheckoutCustomForm/js/model/checkout/custom-checkout-form' 13 | ], function(ko, $, urlFormatter, Component, customer, quote, urlBuilder, errorProcessor, cartCache, formData) { 14 | 'use strict'; 15 | 16 | return Component.extend({ 17 | customFields: ko.observable(null), 18 | formData: formData.customFieldsData, 19 | 20 | /** 21 | * Initialize component 22 | * 23 | * @returns {exports} 24 | */ 25 | initialize: function () { 26 | var self = this; 27 | this._super(); 28 | formData = this.source.get('customCheckoutForm'); 29 | var formDataCached = cartCache.get('custom-form'); 30 | if (formDataCached) { 31 | formData = this.source.set('customCheckoutForm', formDataCached); 32 | } 33 | 34 | this.customFields.subscribe(function(change){ 35 | self.formData(change); 36 | }); 37 | 38 | return this; 39 | }, 40 | 41 | /** 42 | * Trigger save method if form is change 43 | */ 44 | onFormChange: function () { 45 | this.saveCustomFields(); 46 | }, 47 | 48 | /** 49 | * Form submit handler 50 | */ 51 | saveCustomFields: function() { 52 | this.source.set('params.invalid', false); 53 | this.source.trigger('customCheckoutForm.data.validate'); 54 | 55 | if (!this.source.get('params.invalid')) { 56 | var formData = this.source.get('customCheckoutForm'); 57 | var quoteId = quote.getQuoteId(); 58 | var isCustomer = customer.isLoggedIn(); 59 | var url; 60 | 61 | if (isCustomer) { 62 | url = urlBuilder.createUrl('/carts/mine/set-order-custom-fields', {}); 63 | } else { 64 | url = urlBuilder.createUrl('/guest-carts/:cartId/set-order-custom-field', {cartId: quoteId}); 65 | } 66 | 67 | var payload = { 68 | cartId: quoteId, 69 | customFields: formData 70 | }; 71 | var result = true; 72 | $.ajax({ 73 | url: urlFormatter.build(url), 74 | data: JSON.stringify(payload), 75 | global: false, 76 | contentType: 'application/json', 77 | type: 'PUT', 78 | async: true 79 | }).done( 80 | function (response) { 81 | cartCache.set('custom-form', formData); 82 | result = true; 83 | } 84 | ).fail( 85 | function (response) { 86 | result = false; 87 | errorProcessor.process(response); 88 | } 89 | ); 90 | 91 | return result; 92 | } 93 | } 94 | }); 95 | }); -------------------------------------------------------------------------------- /view/frontend/web/js/view/shipping-mixin.js: -------------------------------------------------------------------------------- 1 | 2 | define([ 3 | 'jquery', 4 | 'underscore', 5 | 'Magento_Ui/js/form/form', 6 | 'ko', 7 | 'Magento_Customer/js/model/customer', 8 | 'Magento_Customer/js/model/address-list', 9 | 'Magento_Checkout/js/model/address-converter', 10 | 'Magento_Checkout/js/model/quote', 11 | 'Magento_Checkout/js/action/create-shipping-address', 12 | 'Magento_Checkout/js/action/select-shipping-address', 13 | 'Magento_Checkout/js/model/shipping-rates-validator', 14 | 'Magento_Checkout/js/model/shipping-address/form-popup-state', 15 | 'Magento_Checkout/js/model/shipping-service', 16 | 'Magento_Checkout/js/action/select-shipping-method', 17 | 'Magento_Checkout/js/model/shipping-rate-registry', 18 | 'Magento_Checkout/js/action/set-shipping-information', 19 | 'Magento_Checkout/js/model/step-navigator', 20 | 'Magento_Ui/js/modal/modal', 21 | 'Magento_Checkout/js/model/checkout-data-resolver', 22 | 'Magento_Checkout/js/checkout-data', 23 | 'uiRegistry', 24 | 'mage/translate', 25 | 'Magento_Checkout/js/model/shipping-rate-service' 26 | ], function ( 27 | $, 28 | _, 29 | Component, 30 | ko, 31 | customer, 32 | addressList, 33 | addressConverter, 34 | quote, 35 | createShippingAddress, 36 | selectShippingAddress, 37 | shippingRatesValidator, 38 | formPopUpState, 39 | shippingService, 40 | selectShippingMethodAction, 41 | rateRegistry, 42 | setShippingInformationAction, 43 | stepNavigator, 44 | modal, 45 | checkoutDataResolver, 46 | checkoutData, 47 | registry, 48 | $t 49 | ) { 50 | 'use strict'; 51 | 52 | var mixin = { 53 | 54 | defaults: { 55 | template: 'Bodak_CheckoutCustomForm/shipping' 56 | } 57 | }; 58 | 59 | return function (target) { 60 | return target.extend(mixin); 61 | }; 62 | }); -------------------------------------------------------------------------------- /view/frontend/web/template/checkout/custom-checkout-form.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 | 7 |
8 |
9 |
-------------------------------------------------------------------------------- /view/frontend/web/template/shipping.html: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 |
    6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 19 |
    22 | 23 | 24 | 25 | 26 | 27 | 28 |
    29 |
  • 30 | 31 | 32 |
  • 34 |
    35 |
    38 | 39 | 40 | 41 |
    42 |
  • 43 | 44 | 45 | 91 | --------------------------------------------------------------------------------