This is the second part of the article. In the first article we created the user interface for inputting the shipping comment, prepared the structure for passing the data as an extension attribute and set the input field to be visible only when specific shipping method was selected. You may want to start with the first article and then come back.
In this article we will work on data processing and saving in the database. Lets get started.
Add extension attribute
First thing we need to do is define our extension attribute.
We are going to use Magento\Quote\Api\Data\PaymentInterface which is extensible data interface and allows us to define attributes which we can use. In the first part of this article we set the value for the extension attribute. The values comes from our custom component which is rendered on the shipping step.
Create new table
One of the main advantages of extension attributes is the fact that we do not need to modify the original database schema and we can use our own storage to persist the data. This means that we need to implement this part from scratch. In this example we will use a database table that references the order using a foreign key. This will allow us to persist the data separately and also fetch it easily. Although database schema approach is the suggested way starting from 2.3 we will use the old InstallSchema script to create our table structure. We will look into reworking this using db schema in one of the future articles. Here is the install script.
A few things to note regarding this:
We are creating a new table techflarestudio_shippingcomment_comment
The primary key will be the comment_id field which will be simply incremental value that will ensure a unique identifier for each row
The shipping comment data itself will be saved in a field called comment which will be a text type column
We will also be saving reference to order. So we are adding a new column order_id which is a foreign key and references to sales_order
We are also adding updated_at and creation_time which helps with managing and fetching the data
Create CRUD model
Since we have a new database table we should be able to safely add, delete and modify any records in the table. For this we will create the CRUD model which consists of model class, resource model class, repository class and respective API implementations. In this article we will show only a brief part of the implementation as most of it is unnecessary and unrelated to the topic we are exploring. We will explore repositories and interface approach in a different article. Here are the relevant classes. Lets start with the Model:
We will also be using repository class. We will leave the resource model, collection and interfaces for the reader. Those are fairly standard and do not contain any significant code. You may want to take a look at any of the native entities to see the required code.
Create plugin for saving the data
Once we have our database structure and CRUD models prepared we can proceed with setting up the logic for saving the data. Since we are using PaymentInterface for our extension attribute we need to make sure that the action we observe has access to this data. The payment extension attributes are available when the payment is saved which means that it would be great place to hook in and persist our data. In addition we need the order to be placed when we save this - in order to relate the data in our storage.
One thing to note is that the action for saving payment information differs for guest and logged in sessions which means that there are 2 separate methods we need to hook into:
The logic is fairly similar for both plugins so we will show just the guest user one. We are going to use the after plugin because we are able to access all the data we need - the result returns order id and original argument paymentMethod contains the extension attributes we set earlier.
Lots to digest here:
Firstly we are using after plugin and including the original arguments up until paymentMethod
The we verify if both order id and comment extension attributes are set
We create our shipping comment entity using the factory method for the model class we created previously Techflarestudio\ShippingComment\Model\CommentFactory
We are setting the data and saving the entity using our repository class Techflarestudio\ShippingComment\Model\CommentRepository
For a single store customization the current implementation is sufficient. In future articles we will look into how we can rework this logic to use API interfaces instead of accessing the factory directly.
Make sure to refresh the caches, make sure generated files are cleared. Go to checkout and enter the comment in the shipping section, finish the order. If you followed along then you should be able to see the values persisted in the database. You can verify using:
select * from techflarestudio_shippingcomment_comment;
That is it for today. In the next articles we will work on this even further by using the values we saved - loading the extension attributes in certain areas and showing the values in both customer and admin order views. Stay tuned for part 3.