Skip to Content
Author's profile photo Andy Bai

SAP Business One Service Layer: Attachment manipulation

In this blog, I would like to share another new functionality planned to release in Service Layer 9.2, version for SAP HANA PL03. It is an enhancement to the original attachment operation. ( Actually, it is available in 9.2, version for SAP HANA PL02 and 9.1 Patch 12 as well.)

The supported attachment type list is:

  • pdf
  • doc
  • docx
  • jpg
  • jpeg
  • png
  • txt
  • xls
  • ppt

1 Setup an attachment folder

Attachment folder is generally a shared folder on Windows platform for SAP Business One Client. SL runs on Linux and thus is not allowed to directly access this shared folder. In order to make the attachment folder accessible for SL as well, the Common Internet File System (CIFS) is required. For more information about CIFS, you can visit:

Take the following steps to setup:

1. Create a network shared folder with read and write permissions on Windows (e.g. \\10.58.32.131\temp\andy\attachments2) and configure it as the attachment folder in General Settings in B1 client:

/wp-content/uploads/2016/05/general_setting_form_942659.png

2. Create a corresponding attachment directory on Linux. (e.g. /mnt/attachments2)

3. Mount the Linux folder to Windows folder by running a command like this:

mount -t cifs -o username=xxxxx,password=******,file_mode=0777,dir_mode=0777 "//10.58.32.131/temp/andy/attachments2/" /mnt/attachments2

[How to auto mount when Linux server starts]

To facilitate the configuration convenience for customers, /etc/fstab can be leveraged to automatically mount to Windows shared folder once Linux server reboots. One approach to achieve this is basically as below steps:

  1. Login as root user and create a credential file (e.g /etc/mycifspass) with the below content:
    username=xxxxx password=****** file_mode=0777 dir_mode=0777
  2. Open the system configuration file /etc/fstab and append one line as below://10.58.32.131/temp/andy/attachments2/ /mnt/attachments2 cifs credentials=/etc/mycifspass 0 0
  3. Reboot the Linux server and you will find the Windows shared folder is automatically mounted.

2 Upload an attachment

Considering the source file to attach may be on Linux or on Windows, SL has to support both of these two cases.

2.1 Attach source file from Linux

For this case, uploading the source file (e.g. /home/builder/src_attachment/my_attach_1.dat) as an attachment by sending a request as below:

POST /b1s/v1/Attachments2

 

 

{

 

“Attachments2_Lines”: [

 

{

 

“SourcePath”: “/home/builder/src_attachment”,

 

“FileName”: “my_attach_1”,

 

“FileExtension”: “dat”

 

}

 

]

 

}

 

On success, the response is like:

HTTP/1.1 201 Created

 

 

{

 

“AbsoluteEntry”: “1”,

 

“Attachments2_Lines”: [

 

{

 

“SourcePath”: “/home/builder/src_attachment”,

 

“FileName”: “my_attach_1”,

 

“FileExtension”: “dat”,

 

“AttachmentDate”: “2016-03-25”,

 

“UserID”: “1”,

 

“Override”: “tNO”

 

}

 

]

 

}

 

and the source file is saved in the destination attachment folder on Linux (/mnt/attachments2):

/wp-content/uploads/2016/05/my_attach_1_linux_942660.png

Then open the Windows folder (\\10.58.32.131\temp\andy\attachments), you will find the source file is saved there as well:

/wp-content/uploads/2016/05/my_attach_1_windows_942661.png

2.2 Attach source file from Windows

One way to add an attachment on Windows is to use HTTP POST method. The request MUST contain a Content-Type header specifying a content type of multipart/form-data and a boundary specification as: Always use HTTP POST method to add an attachment. The request MUST contain a Content-Typeheader specifying a content type of multipart/form-data and a boundary specification as:

Content-Type: multipart/form-data;boundary=<Boundary>

The body is separated by the boundary defined in the Content-Type header, like:


–<Boundary>

 

Content-Disposition: form-data; name=”files”; filename=”<file1>”

 

Content-Type: <content type of file1>

 

 

<file1 content>

 

–<Boundary> Content-Disposition: form-data; name=”files”; filename=”<file2>”

 

Content-Type: <content type of file2>

 

 

<file2 content>

 

–<Boundary>–

For example, if you want to pack two files into one attachment to post, send the request like:


POST /b1s/v1/Attachments2 HTTP/1.1

 

Content-Type: multipart/form-data; boundary=—-WebKitFormBoundaryUmZoXOtOBNCTLyxT

 

 

——WebKitFormBoundaryUmZoXOtOBNCTLyxT

 

Content-Disposition: form-data; name=”files”; filename=”line1.txt”

 

Content-Type: text/plain

 

 

Introduction

 

B1 Service Layer (SL) is a new generation of extension API for consuming B1 objects and services

 

via web service with high scalability and high availability.

 

——WebKitFormBoundaryUmZoXOtOBNCTLyxT

 

Content-Disposition: form-data; name=”files”; filename=”line2.jpg”

 

Content-Type: image/jpeg

 

 

 

<image binary data>

 

——WebKitFormBoundaryUmZoXOtOBNCTLyxT–

On success, the response is like:


HTTP/1.1 201 Created

 

 

{

 

“odata.metadata”: “https://10.58.136.174:50000/b1s/v1/$metadata#Attachments2/@Element“,

 

“AbsoluteEntry”: “3”,

 

“Attachments2_Lines”: [

 

{

 

“SourcePath”: “/tmp/sap_b1_i066088/ServiceLayer/Attachments2/”,

 

“FileName”: “line1”,

 

“FileExtension”: “txt”,

 

“AttachmentDate”: “2016-04-06”,

 

“UserID”: “1”,

 

“Override”: “tNO”

 

},

 

{

 

“SourcePath”: “/tmp/sap_b1_i066088/ServiceLayer/Attachments2/”,

 

“FileName”: “line2”,

 

“FileExtension”: “png”,

 

“AttachmentDate”: “2016-04-06”,

 

“UserID”: “1”,

 

“Override”: “tNO”

 

}

 

]

 

}

3 Download attachment

By default, the first attachment line is downloaded if there are multiple attachment lines in one attachment. To download it, $value is required to append to the end of the attachment retrieval URL. For example:

GET /b1s/v1/Attachments2(3)/$value

On success, the response is like this in browser:

/wp-content/uploads/2016/05/line1_942665.png

If you want to download the attachment line other than the first attachment line, full file name (including the file extension) needs to be specified in the request URL. For example:

GET /b1s/v1/Attachments2(3)/$value?filename='line2.png'

On success, the response is like this in browser:

/wp-content/uploads/2016/05/line2_942666.png

4 Update attachment

SL allows you to update an attachment via PATCH and there are two typical cases for this operation.

[Update an existing attachment line]

If the attachment line to update already exists, it is just replaced by the new attachment line. For Example:


PATCH /b1s/v1/Attachments2(3) HTTP/1.1

 

Content-Type: multipart/form-data; boundary=—-WebKitFormBoundaryUmZoXOtOBNCTLyxT

 

 

——WebKitFormBoundaryUmZoXOtOBNCTLyxT

 

Content-Disposition: form-data; name=”files”; filename=”line1.txt”

 

Content-Type: text/plain

 

 

Introduction(Updated)

 

B1 Service Layer (SL) is a new generation of extension API for consuming B1 objects and services

 

via web service with high scalability and high availability.

 

——WebKitFormBoundaryUmZoXOtOBNCTLyxT–

On success, HTTP code 204 is returned without content.

HTTP/1.1 204 No Content

To check the updated attachment line, send a request like this:

GET /b1s/v1/Attachments2(3)/$value?filename='line1.txt'

On success, the response is like this in browser:

/wp-content/uploads/2016/05/line1_patch_942667.png

[Add one attachment line if not existing]

If the attachment line to update doesn’t exist, the new attachment line is appended to the last existing attachment line. Example:


PATCH /b1s/v1/Attachments2(3) HTTP/1.1

 

Content-Type: multipart/form-data; boundary=—-WebKitFormBoundaryUmZoXOtOBNCTLyxT

 

 

——WebKitFormBoundaryUmZoXOtOBNCTLyxT

 

Content-Disposition: form-data; name=”files”; filename=”/wp-content/uploads/2016/05/line3_942668.png”

 

Content-Type: image/jpeg

 

 

<binary data>

 

——WebKitFormBoundaryUmZoXOtOBNCTLyxT–

On success, HTTP code 204 is returned without content.

HTTP/1.1 204 No Content

To check the newly created attachment line, send a request like this:

GET /b1s/v1/Attachments2(3)/$value?filename='line3.png'

On success, the response is like this in browser:

/wp-content/uploads/2016/05/line3_942668.png

[Note]

  • It is not allowed to delete an attachment or attachment line from the business logic perspective.

Assigned Tags

      11 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Ralph Oliveira
      Ralph Oliveira

      Thanks Andy! Really appreciated!

      Partners were dying for it! 🙂

      Author's profile photo Former Member
      Former Member

      Hi Andy,

      I have followed each and every step in the article but no luck.

      I am getting below issue while uploading the file.

      {
        "error" : {
        "code" : -5002,
        "message" : {
        "lang" : "en-us",
        "value" : "Attachments folder not defined, or Attachments folder has been changed or removed "
        }
        }
      }

      Author's profile photo Rogerio Souza
      Rogerio Souza

      ola ....    qual a solucao que aplicou para resolver isso??

      +55 11 984152748

      Author's profile photo Andy Bai
      Andy Bai
      Blog Post Author

      I do not quite understand your question.

      Anyway, the error message means the attachment folder is not defined.

      You can check this by opening b1 client | general settings and find out the attachment folder.

      meanwhile, you need to set a mount point in Linux to the attachment folder.

      More details, please see the service layer document.

      Author's profile photo Rogerio Souza
      Rogerio Souza

      Hi Andy,

      I have followed each and every step in the article but no luck.

      I am getting below issue while uploading the file.

      {
        "error" : {
        "code" : -5002,
        "message" : {
        "lang" : "en-us",
        "value" : "Attachments folder not defined, or Attachments folder has been changed or removed "
        }
        }
      }

      Author's profile photo Andy Bai
      Andy Bai
      Blog Post Author

      I cannot figure out the cause just by the error message.

      more details are needed.

      anyway, you can approach to the support engineer or report an incident to sap.

      thanks for the understanding.

      Author's profile photo Sebastian Kleiner
      Sebastian Kleiner

      Is it possible to define different mount points because we have different companies on one server (cloud)?
      In terms of security is currently not applicable.

      Thanks
      Seb

      Author's profile photo Andy Bai
      Andy Bai
      Blog Post Author

      Yes. Possible.

      Author's profile photo Doug Gerlach
      Doug Gerlach

      What format is the binary data expected to be in for saving an image from Windows?  The data just says <image binary data> but does not say format?  I have tried base 64 string.

      Author's profile photo Charles Simpson
      Charles Simpson

      Did you get any response to this?

      Author's profile photo Doug Gerlach
      Doug Gerlach

      no, but we were able to figure it out, we had to write the bytes to the response stream of the web call.