From 5b4dc57afeb3281b9846e529464eb0b5fa0c70e5 Mon Sep 17 00:00:00 2001
From: "a.kraynov" <a.kraynov@astrio.net>
Date: Thu, 29 Jul 2021 17:32:25 +0400
Subject: [PATCH 1/2] #516:task11:complete 1 and 2 subtasks

---
 .../Plugin/LayoutProcessorPlugin.php          | 39 +++++++++++
 Astrio/TrainingModule11/etc/di.xml            |  5 ++
 Astrio/TrainingModule11/etc/module.xml        |  7 ++
 Astrio/TrainingModule11/registration.php      |  6 ++
 .../frontend/layout/checkout_index_index.xml  | 50 ++++++++++++++
 .../frontend/web/js/model/my-validator.js     | 23 +++++++
 .../view/frontend/web/js/view/my-step-view.js | 68 +++++++++++++++++++
 .../frontend/web/js/view/my-validation.js     | 11 +++
 .../view/frontend/web/template/my-step.html   | 17 +++++
 9 files changed, 226 insertions(+)
 create mode 100644 Astrio/TrainingModule11/Plugin/LayoutProcessorPlugin.php
 create mode 100644 Astrio/TrainingModule11/etc/di.xml
 create mode 100644 Astrio/TrainingModule11/etc/module.xml
 create mode 100644 Astrio/TrainingModule11/registration.php
 create mode 100644 Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml
 create mode 100644 Astrio/TrainingModule11/view/frontend/web/js/model/my-validator.js
 create mode 100644 Astrio/TrainingModule11/view/frontend/web/js/view/my-step-view.js
 create mode 100644 Astrio/TrainingModule11/view/frontend/web/js/view/my-validation.js
 create mode 100644 Astrio/TrainingModule11/view/frontend/web/template/my-step.html

diff --git a/Astrio/TrainingModule11/Plugin/LayoutProcessorPlugin.php b/Astrio/TrainingModule11/Plugin/LayoutProcessorPlugin.php
new file mode 100644
index 0000000..39da78c
--- /dev/null
+++ b/Astrio/TrainingModule11/Plugin/LayoutProcessorPlugin.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Astrio\TrainingModule11\Plugin;
+
+class LayoutProcessorPlugin {
+
+    public function afterProcess(\Magento\Checkout\Block\Checkout\LayoutProcessor $processor, $jsLayout)
+    {
+        $customAttributeCode = 'custom_field';
+        $customField = [
+            'component' => 'Magento_Ui/js/form/element/abstract',
+            'config' => [
+                // customScope is used to group elements within a single form (e.g. they can be validated separately)
+                'customScope' => 'shippingAddress.custom_attributes',
+                'customEntry' => null,
+                'template' => 'ui/form/field',
+                'elementTmpl' => 'ui/form/element/input',
+                'tooltip' => [
+                    'description' => 'this is what the field is for',
+                ]
+            ],
+            'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
+            'label' => 'Custom Attribute',
+            'provider' => 'checkoutProvider',
+            'sortOrder' => 0,
+            'validation' => [
+                'required-entry' => true
+            ],
+            'options' => [],
+            'filterBy' => null,
+            'customEntry' => null,
+            'visible' => true,
+            'value' => ''
+        ];
+
+        $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;
+        return $jsLayout;
+    }
+}
diff --git a/Astrio/TrainingModule11/etc/di.xml b/Astrio/TrainingModule11/etc/di.xml
new file mode 100644
index 0000000..08fd746
--- /dev/null
+++ b/Astrio/TrainingModule11/etc/di.xml
@@ -0,0 +1,5 @@
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
+        <plugin name="Add_Field_Plugin" type="Astrio\TrainingModule11\Plugin\LayoutProcessorPlugin" sortOrder="10" disabled="false"  />
+    </type>
+</config>
diff --git a/Astrio/TrainingModule11/etc/module.xml b/Astrio/TrainingModule11/etc/module.xml
new file mode 100644
index 0000000..1aead1a
--- /dev/null
+++ b/Astrio/TrainingModule11/etc/module.xml
@@ -0,0 +1,7 @@
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:fraVendor_Modulemework:Module/etc/module.xsd">
+    <module name="Astrio_TrainingModule11" setup_version = "1.0.0">
+        <sequence>
+            <module name="Magento_Checkout" />
+        </sequence>
+    </module>
+</config>
diff --git a/Astrio/TrainingModule11/registration.php b/Astrio/TrainingModule11/registration.php
new file mode 100644
index 0000000..bcc5b85
--- /dev/null
+++ b/Astrio/TrainingModule11/registration.php
@@ -0,0 +1,6 @@
+<?php
+\Magento\Framework\Component\ComponentRegistrar::register(
+    \Magento\Framework\Component\ComponentRegistrar::MODULE,
+    'Astrio_TrainingModule11',
+    __DIR__
+);
diff --git a/Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml b/Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml
new file mode 100644
index 0000000..540f9ab
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <!-- The new step you add -->
+                                        <item name="my-new-step" xsi:type="array">
+                                            <item name="component" xsi:type="string">Astrio_TrainingModule11/js/view/my-step-view</item>
+                                            <!-- To display step content before shipping step "sortOrder" value should be < 1 -->
+                                            <!-- To display step content between shipping step and payment step  1 < "sortOrder" < 2 -->
+                                            <!-- To display step content after payment step "sortOrder" > 2 -->
+                                            <item name="sortOrder" xsi:type="string">2</item>
+                                            <item name="children" xsi:type="array">
+                                                <!-- add here child component declaration for your step -->
+                                            </item>
+                                        </item>
+
+                                        <item name="billing-step" xsi:type="array">
+                                            <item name="children" xsi:type="array">
+                                                <item name="payment" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="additional-payment-validators" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <!-- Declare your validation. START -->
+                                                                <item name="your-validator" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Astrio_TrainingModule11/js/view/my-validation</item>
+                                                                </item>
+                                                                <!-- Declare your validation. END -->
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
diff --git a/Astrio/TrainingModule11/view/frontend/web/js/model/my-validator.js b/Astrio/TrainingModule11/view/frontend/web/js/model/my-validator.js
new file mode 100644
index 0000000..0f0707a
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/web/js/model/my-validator.js
@@ -0,0 +1,23 @@
+define([
+        'jquery',
+        'mage/translate',
+        'Magento_Ui/js/model/messageList'
+    ], function ($, $t, messageList) {
+        'use strict';
+
+        return {
+            validate: function () {
+                let isValid = false; // Put your validation logic here
+                // alert($('#myTextFieldId').val());
+                // alert($('[name="custom_attributes[custom_field]"]').val());
+                if ($('#myTextFieldId').val() == $('[name="custom_attributes[custom_field]"]').val())
+                    isValid = true;
+                else {
+                    isValid = false;
+                    messageList.addErrorMessage({ message: $t('fields is not equal') });
+                }
+                return isValid;
+            }
+        }
+    }
+);
diff --git a/Astrio/TrainingModule11/view/frontend/web/js/view/my-step-view.js b/Astrio/TrainingModule11/view/frontend/web/js/view/my-step-view.js
new file mode 100644
index 0000000..636a869
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/web/js/view/my-step-view.js
@@ -0,0 +1,68 @@
+define([
+        'ko',
+        'uiComponent',
+        'underscore',
+        'Magento_Checkout/js/model/step-navigator'
+    ], function (ko, Component, _, stepNavigator) {
+        'use strict';
+
+        /**
+         * my-step.html - is the name of the component's .html template,
+         * Astrio_Checkout  - is the name of the your module directory.
+         */
+        return Component.extend({
+            defaults: {
+                template: 'Astrio_TrainingModule11/my-step.html'
+            },
+
+            // add here your logic to display step,
+            isVisible: ko.observable(true),
+
+            /**
+             * @returns {*}
+             */
+            initialize: function () {
+                this._super();
+                // register your step
+                stepNavigator.registerStep(
+                    // step code will be used as step content id in the component template
+                    'step_code',
+                    // step alias
+                    null,
+                    // step title value
+                    'Step Title',
+                    // observable property with logic when display step or hide step
+                    this.isVisible,
+
+                    _.bind(this.navigate, this),
+
+                    /**
+                     * sort order value
+                     * 'sort order value' < 10: step displays before shipping step;
+                     * 10 < 'sort order value' < 20 : step displays between shipping and payment step
+                     * 'sort order value' > 20 : step displays after payment step
+                     */
+                    15
+                );
+                return this;
+            },
+
+            /**
+             * The navigate() method is responsible for navigation between checkout step
+             * during checkout. You can add custom logic, for example some conditions
+             * for switching to your custom step
+             * When the user navigates to the custom step via url anchor or back button we_must show step manually here
+             */
+            navigate: function () {
+                this.isVisible(true);
+            },
+
+            /**
+             * @returns void
+             */
+            navigateToNextStep: function () {
+                stepNavigator.next();
+            }
+        });
+    }
+);
diff --git a/Astrio/TrainingModule11/view/frontend/web/js/view/my-validation.js b/Astrio/TrainingModule11/view/frontend/web/js/view/my-validation.js
new file mode 100644
index 0000000..263584d
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/web/js/view/my-validation.js
@@ -0,0 +1,11 @@
+define([
+        'uiComponent',
+        'Magento_Checkout/js/model/payment/additional-validators',
+        'Astrio_TrainingModule11/js/model/my-validator'
+    ], function (Component, additionalValidators, yourValidator) {
+        'use strict';
+
+        additionalValidators.registerValidator(yourValidator);
+        return Component.extend({});
+    }
+);
diff --git a/Astrio/TrainingModule11/view/frontend/web/template/my-step.html b/Astrio/TrainingModule11/view/frontend/web/template/my-step.html
new file mode 100644
index 0000000..c0fb4b9
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/web/template/my-step.html
@@ -0,0 +1,17 @@
+<li id="step_code" data-bind="fadeVisible: isVisible">
+    <div class="step-title" data-bind="i18n: 'Step Title'" data-role="title"></div>
+    <div id="checkout-step-title"
+         class="step-content"
+         data-role="content">
+        <form data-bind="submit: navigateToNextStep" novalidate="novalidate">
+            <div class="actions-toolbar">
+                <div class="primary">
+                    <input type="text" id="myTextFieldId" name="myTextField" size="10">
+                    <button data-role="opc-continue" type="submit" class="button action continue primary">
+                        <span><!-- ko i18n: 'Next'--><!-- /ko --></span>
+                    </button>
+                </div>
+            </div>
+        </form>
+    </div>
+</li>
-- 
GitLab


From a5026261ec9baaae9f1d1d6004bcf76b24b4d8da Mon Sep 17 00:00:00 2001
From: "a.kraynov" <a.kraynov@astrio.net>
Date: Fri, 30 Jul 2021 12:44:18 +0400
Subject: [PATCH 2/2] #516:task11:add 3 and 4 subtasks

---
 .../Model/Carrier/CustomShipping.php          | 97 +++++++++++++++++++
 .../TrainingModule11/Model/PaymentMethod.php  | 15 +++
 .../TrainingModule11/etc/adminhtml/system.xml | 51 ++++++++++
 Astrio/TrainingModule11/etc/config.xml        | 25 +++++
 Astrio/TrainingModule11/etc/module.xml        |  4 +
 Astrio/TrainingModule11/etc/zip_codes.xml     | 11 +++
 .../frontend/layout/checkout_index_index.xml  | 17 ++++
 .../payment/method-renderer/payment-method.js | 13 +++
 .../frontend/web/js/view/payment/registrar.js | 18 ++++
 .../web/template/payment/method-template.html | 26 +++++
 10 files changed, 277 insertions(+)
 create mode 100644 Astrio/TrainingModule11/Model/Carrier/CustomShipping.php
 create mode 100644 Astrio/TrainingModule11/Model/PaymentMethod.php
 create mode 100644 Astrio/TrainingModule11/etc/adminhtml/system.xml
 create mode 100644 Astrio/TrainingModule11/etc/config.xml
 create mode 100644 Astrio/TrainingModule11/etc/zip_codes.xml
 create mode 100644 Astrio/TrainingModule11/view/frontend/web/js/view/payment/method-renderer/payment-method.js
 create mode 100644 Astrio/TrainingModule11/view/frontend/web/js/view/payment/registrar.js
 create mode 100644 Astrio/TrainingModule11/view/frontend/web/template/payment/method-template.html

diff --git a/Astrio/TrainingModule11/Model/Carrier/CustomShipping.php b/Astrio/TrainingModule11/Model/Carrier/CustomShipping.php
new file mode 100644
index 0000000..3748e7e
--- /dev/null
+++ b/Astrio/TrainingModule11/Model/Carrier/CustomShipping.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Astrio\TrainingModule11\Model\Carrier;
+
+use Magento\Quote\Model\Quote\Address\RateRequest;
+use Magento\Shipping\Model\Carrier\AbstractCarrier;
+use Magento\Shipping\Model\Carrier\CarrierInterface;
+
+/**
+ * Class CustomShipping
+ * @package Astrio\Checkout\Model\Carrier
+ */
+class CustomShipping extends AbstractCarrier implements CarrierInterface
+{
+    /**
+     * @var string
+     */
+    protected $_code = 'custom_shipping';
+
+    /**
+     * @var bool
+     */
+    protected $_isFixed = true;
+
+    /**
+     * @var \Magento\Shipping\Model\Rate\ResultFactory
+     */
+    private $rateResultFactory;
+
+    /**
+     * @var \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory
+     */
+    private $rateMethodFactory;
+
+    /**
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory
+     * @param \Psr\Log\LoggerInterface $logger
+     * @param \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory
+     * @param \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
+        \Psr\Log\LoggerInterface $logger,
+        \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
+        \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $rateMethodFactory,
+        array $data = []
+    ) {
+        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
+        $this->rateResultFactory = $rateResultFactory;
+        $this->rateMethodFactory = $rateMethodFactory;
+    }
+
+    /**
+     * Custom Shipping Rates Collector
+     *
+     * @param RateRequest $request
+     * @return \Magento\Shipping\Model\Rate\Result|bool
+     */
+    public function collectRates(RateRequest $request)
+    {
+        if (!$this->getConfigFlag('active')) {
+            return false;
+        }
+
+        /** @var \Magento\Shipping\Model\Rate\Result $result */
+        $result = $this->rateResultFactory->create();
+
+        /** @var \Magento\Quote\Model\Quote\Address\RateResult\Method $method */
+        $method = $this->rateMethodFactory->create();
+
+        $method->setCarrier($this->_code);
+        $method->setCarrierTitle($this->getConfigData('title'));
+
+        $method->setMethod($this->_code);
+        $method->setMethodTitle($this->getConfigData('name'));
+
+        $shippingCost = (float)$this->getConfigData('shipping_cost');
+
+        $method->setPrice($shippingCost);
+        $method->setCost($shippingCost);
+
+        $result->append($method);
+
+        return $result;
+    }
+
+    /**
+     * @return array
+     */
+    public function getAllowedMethods()
+    {
+        return [$this->_code => $this->getConfigData('name')];
+    }
+}
diff --git a/Astrio/TrainingModule11/Model/PaymentMethod.php b/Astrio/TrainingModule11/Model/PaymentMethod.php
new file mode 100644
index 0000000..271e27f
--- /dev/null
+++ b/Astrio/TrainingModule11/Model/PaymentMethod.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Astrio\TrainingModule11\Model;
+
+
+class PaymentMethod extends \Magento\Payment\Model\Method\AbstractMethod
+{
+    /**
+     * Payment code
+     * @var string
+     */
+    protected $_code = 'test_payment';
+
+    protected $_canAuthorize = true;
+}
diff --git a/Astrio/TrainingModule11/etc/adminhtml/system.xml b/Astrio/TrainingModule11/etc/adminhtml/system.xml
new file mode 100644
index 0000000..5c54d5d
--- /dev/null
+++ b/Astrio/TrainingModule11/etc/adminhtml/system.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
+    <system>
+        <section id="payment">
+            <group id="test_payment" translate="label" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Test Payment</label>
+                <field id="active" translate="label comment" sortOrder="1" type="select" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Enable</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+            </group>
+        </section>
+        <section id="carriers" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
+            <group id="custom_shipping" translate="label" type="text" sortOrder="900" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Custom Shipping Module</label>
+                <field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
+                    <label>Enabled</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="title" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Title</label>
+                </field>
+                <field id="name" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Method Name</label>
+                </field>
+                <field id="shipping_cost" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0" >
+                    <label>Shipping Cost</label>
+                    <validate>validate-number validate-zero-or-greater</validate>
+                </field>
+                <field id="sallowspecific" translate="label" type="select" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
+                    <label>Ship to Applicable Countries</label>
+                    <frontend_class>shipping-applicable-country</frontend_class>
+                    <source_model>Magento\Shipping\Model\Config\Source\Allspecificcountries</source_model>
+                </field>
+                <field id="specificcountry" translate="label" type="multiselect" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Ship to Specific Countries</label>
+                    <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
+                    <can_be_empty>1</can_be_empty>
+                </field>
+                <field id="showmethod" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Show Method if Not Applicable</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                    <frontend_class>shipping-skip-hide</frontend_class>
+                </field>
+                <field id="sort_order" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Sort Order</label>
+                </field>
+            </group>
+        </section>
+    </system>
+</config>
diff --git a/Astrio/TrainingModule11/etc/config.xml b/Astrio/TrainingModule11/etc/config.xml
new file mode 100644
index 0000000..214b185
--- /dev/null
+++ b/Astrio/TrainingModule11/etc/config.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
+    <default>
+        <payment>
+            <test_payment>
+                <payment_action>authorize</payment_action> <!-- You can use another method like capture -->
+                <model>Astrio\TrainingModule11\Model\PaymentMethod</model>
+                <active>1</active>
+                <title>Test Payment</title>
+                <order_status>pending_payment</order_status> <!-- Set default order status -->
+            </test_payment>
+        </payment>
+        <carriers>
+            <custom_shipping>
+                <active>0</active>
+                <title>Custom Shipping Title</title>
+                <name>Custom Shipping Method Name</name>
+                <shipping_cost>10</shipping_cost>
+                <sallowspecific>0</sallowspecific>
+                <sort_order>15</sort_order>
+                <model>Astrio\TrainingModule11\Model\Carrier\CustomShipping</model>
+            </custom_shipping>
+        </carriers>
+    </default>
+</config>
diff --git a/Astrio/TrainingModule11/etc/module.xml b/Astrio/TrainingModule11/etc/module.xml
index 1aead1a..21ae481 100644
--- a/Astrio/TrainingModule11/etc/module.xml
+++ b/Astrio/TrainingModule11/etc/module.xml
@@ -2,6 +2,10 @@
     <module name="Astrio_TrainingModule11" setup_version = "1.0.0">
         <sequence>
             <module name="Magento_Checkout" />
+            <module name="Magento_Store"/>
+            <module name="Magento_Sales"/>
+            <module name="Magento_Quote"/>
+            <module name="Magento_SalesRule"/>
         </sequence>
     </module>
 </config>
diff --git a/Astrio/TrainingModule11/etc/zip_codes.xml b/Astrio/TrainingModule11/etc/zip_codes.xml
new file mode 100644
index 0000000..56e61d4
--- /dev/null
+++ b/Astrio/TrainingModule11/etc/zip_codes.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Directory:etc/zip_codes.xsd">
+    <!-- Specify the country ISO code-->
+    <zip countryCode="US">
+        <!-- You can specify several patterns for one country -->
+        <codes>
+            <code id="my_pattern_1" active="true" example="1A">^[0-9]{1}[A-Z]{1}$</code>
+            <code id="pattern_2" active="true" example="12">^[0-9]{2}$</code>
+        </codes>
+    </zip>
+</config>
diff --git a/Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml b/Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml
index 540f9ab..ff98f0e 100644
--- a/Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml
+++ b/Astrio/TrainingModule11/view/frontend/layout/checkout_index_index.xml
@@ -34,9 +34,26 @@
                                                                 <!-- Declare your validation. END -->
                                                             </item>
                                                         </item>
+                                                        <!-- Declare the payment method (the component that registrates in the list). START -->
+                                                        <item name="renders" xsi:type="array">
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="test_payment" xsi:type="array">
+                                                                    <!-- Example of value: Magento_Authorizenet/js/view/payment/authorizenet -->
+                                                                    <item name="component" xsi:type="string">Astrio_TrainingModule11/js/view/payment/registrar</item>
+                                                                    <item name="methods" xsi:type="array">
+
+                                                                        <!-- Add this if your payment method requires entering a billing address -->
+                                                                        <item name="test_payment" xsi:type="array">
+                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
                                                     </item>
                                                 </item>
                                             </item>
+                                            <item name="component" xsi:type="string">uiComponent</item>
                                         </item>
                                     </item>
                                 </item>
diff --git a/Astrio/TrainingModule11/view/frontend/web/js/view/payment/method-renderer/payment-method.js b/Astrio/TrainingModule11/view/frontend/web/js/view/payment/method-renderer/payment-method.js
new file mode 100644
index 0000000..65e3948
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/web/js/view/payment/method-renderer/payment-method.js
@@ -0,0 +1,13 @@
+define([
+        'Magento_Checkout/js/view/payment/default'
+    ], function (Component) {
+        'use strict';
+
+        return Component.extend({
+            defaults: {
+                template: 'Astrio_TrainingModule11/payment/method-template'
+            },
+            // add required logic here
+        });
+    }
+);
diff --git a/Astrio/TrainingModule11/view/frontend/web/js/view/payment/registrar.js b/Astrio/TrainingModule11/view/frontend/web/js/view/payment/registrar.js
new file mode 100644
index 0000000..273af91
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/web/js/view/payment/registrar.js
@@ -0,0 +1,18 @@
+define([
+        'uiComponent',
+        'Magento_Checkout/js/model/payment/renderer-list'
+    ], function (Component, rendererList) {
+        'use strict';
+
+        rendererList.push(
+            {
+                type: 'test_payment',
+                component: 'Astrio_TrainingModule11/js/view/payment/method-renderer/payment-method'
+            },
+            // other payment method renderers if required
+        );
+
+        /** Add view logic here if needed */
+        return Component.extend({});
+    }
+);
diff --git a/Astrio/TrainingModule11/view/frontend/web/template/payment/method-template.html b/Astrio/TrainingModule11/view/frontend/web/template/payment/method-template.html
new file mode 100644
index 0000000..edcbf33
--- /dev/null
+++ b/Astrio/TrainingModule11/view/frontend/web/template/payment/method-template.html
@@ -0,0 +1,26 @@
+<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
+    <div class="payment-method-title field choice">
+        <input type="radio"
+               name="payment[method]"
+               class="radio"
+               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()"/>
+        <label data-bind="attr: {'for': getCode()}" class="label"><span data-bind="text: getTitle()"></span></label>
+    </div>
+    <div class="payment-method-content">
+        <div class="actions-toolbar">
+            <div class="primary">
+                <button class="action primary checkout"
+                        type="submit"
+                        data-bind="
+                            click: placeOrder,
+                            attr: {title: $t('Place Order')},
+                            css: {disabled: !isPlaceOrderActionAllowed()},
+                            enable: (getCode() == isChecked())
+                        "
+                        disabled>
+                    <span data-bind="i18n: 'Place Order'"></span>
+                </button>
+            </div>
+        </div>
+    </div>
+</div>
-- 
GitLab