Wednesday, August 29, 2018

Attachments in sales orders with Hybris Commerce using MultipartFile

In this blog I will describe how to enable users to add file attachments to their cart and save them in the SAP ECC back-end.




Front-end


Let’s look at the front-end first. We add this functionality to the order details section of the checkout page as you can see in above screenshot. We used the DropzoneJS open source library to add a drop zone where the user can drag files to and added a ‘browse’ link which opens the file open dialog box of the browser.

Once a user drags a file to the drop zone…



…the attachment is uploaded. The list of filenames of all attachments is displayed followed by a trashcan, so users can remove them too. As soon as the order is submitted, the attachments are saved in the SAP ECC back-end.



Back-end


Let’s focus now on the back-end implementation.

Controller


We add the addAttachment() method to the page controller which is called as soon as a user adds an attachment to the cart on the checkout page. It takes a MultipartFile as input which is a standard part of the Spring Framework. You can conveniently access the file name, the content type and content stream.

Our method has below code and does the following.


It first validates if the file extension is allowed. I don’t further describe this step here, but we check this to block .exe, .zip and other possible harmful formats. If successful we call addAttachment() in the AttachmentFacadeImpl class (also not shown here) which calls addAttachment() in AttachmentServiceImpl which I will discuss later.

We hold the list of attachments as an attribute in the session. We add this attribute to the model and end by returning the list of attachments with possible errors as the following JSON.



Service


In AttachmentServiceImpl we create method addAttachment() like this.


It calls createAttachmentFromFile() which saves the metadata of the attachment (e.g. name, type, size) and status (e.g. created, saved in back-end) as a model in the database. This step is optional, and I won’t describe this further here, but this can be helpful to easily monitor the different steps in processing the attachments.

Then, it calls createFile().


This converts the content stream of the MultipartFile to a File object and stores it temporarily on the file system of the server. This file is automatically removed as soon as the session is closed. As you can imagine, we don’t want to store the file contents in the session itself as they may be very large.

By the way, if you want to control the maximum size limit you can set it like this in your spring.xml file.


After this step, we update the status of our model instance with updateStatus(). Again, this is optional. And finish by adding our model instance to the list of attachments in our session attribute, so we can easily access it later.

In our service we have some additional methods for other functions and housekeeping, like deleteAttachment() which deletes the file from the file system and our session attribute, but I won’t describe them here.

Outbound service


Now the user can upload and delete attachments from his cart. But how are they actually saved in the SAP back-end? Let’s look at this now.

We want to save the attachments in SAP ECC when the order is saved. Unfortunately, we can’t do this in one step. We first need to save the order and immediately after we add the attachments.

So we override placeOrder() in class SapOrdermgmtB2BCheckoutFacade and first call super.placeOrder() and then call saveAttachmentsInBackend() in AttachmentFacadeImpl, which is like this:


It loops on the list of attachments and for each it updates the order number in the model (optional), saves the attachment to the order in SAP and deletes it from the file system. It ends by deleting the list of attachment from the session, so we start a new cart with a fresh list.

Saving the attachment in SAP goes like this. It calls createAttachmentInSap() in SapAttachmentServiceImpl, which eventually calls createAttachmentInSap() in SapAttachmentBackendERP. I won’t bore you with all the boilerplate code, but it calls function module SO_DOCUMENT_INSERT in SAP ECC which save the attachment to our order.

Actually, we created a small wrapper around it that does a few things more, but that’s not so relevant for now. More important to share with you here is that we need to handle text and binary files differently and the line length of the structure we need to fill is limited to 255 characters. We take care of this with the following code:


Method fillTableFromTextFile()


Method fillTableFromBinaryFile()


I hope you found it helpful to see how we can handle attachments in Hybris Commerce and SAP ECC and that you can benefit from this example for your own projects.