Code Monkey home page Code Monkey logo

php-sapb1's Introduction

SAPb1

A simple and easy to use PHP library for SAP Business One Service Layer API.

Usage

Create an array to store your SAP Business One Service Layer configuration details.

$config = [
    'https' => true,
    'host' => 'IP or Hostname',
    'port' => 50000,
    'sslOptions' => [
        "cafile" => "path/to/certificate.crt",
        "verify_peer" => true,
        "verify_peer_name" => true,
    ],
    'version' => 2
];

Create a new Service Layer session.

$sap = SAPClient::createSession($config, 'SAP UserName', 'SAP Password', 'Company');

The static createSession() method will return a new instance of SAPClient. The SAPClient object provides a service($name) method which returns a new instance of Service with the specified name. Using this Service object you can perform CRUD actions.

Querying A Service

The queryBuilder() method of the Service class returns a new instance of Query. The Query class allows you to use chainable methods to filter the requested service.

The following code sample shows how to filter Sales Orders using the Orders service.

$sap = SAPClient::createSession($config, 'SAP UserName', 'SAP Password', 'Company');
$orders = $sap->getService('Orders');

$result = $orders->queryBuilder()
    ->select('DocEntry,DocNum')
    ->orderBy('DocNum', 'asc')
    ->limit(5)
    ->findAll(); 

The findAll() method will return a collection of records that match the search criteria. To return a specific record using an id use the find($id) method.

...
$orders = $sap->getService('Orders');

$result = $orders->queryBuilder()
    ->select('DocEntry,DocNum')
    ->find(123456); // DocEntry value

Depending on the service, $id may be a numeric value or a string. If you want to know which field is used as the id for a service, call the getMetaData() method on the Service object as shown below.

...
$meta = $orders->getMetaData();

Creating A Service

The following code sample shows how to create a new Sales Order using the create() method of the Service object.

...
$orders = $sap->getService('Orders');

$result = $orders->create([
    'CardCode' => 'BP Card Code',
    'DocDueDate' => 'Doc due date',
    'DocumentLines' => [
        [
            "ItemCode" => "Item Code",
            "Quantity" => 100,
        ]
    ]
]);

You must provide any User Defined Fields that are required to create a Sales Order. If successful, the newly created Sales Order will be returned as an object.

Updating A Service

The following code sample demonstrates how to update a service using the update() method of the Service object.

...
$orders = $sap->getService('Orders');

$result = $orders->update(19925, [
    'Comments' => 'Comment added here'
]);

Note that the first argument to the update() method is the id of the entity to update. In the case of a Sales Order the id is the DocEntry field. If the update is successful a boolean true value is returned.

Adding Headers

You can specify oData headers by calling the headers() method on a Service instance with an array of headers.

...
$orders = $sap->getService('Orders');
$orders->headers(['Prefer' => 'odata.maxpagesize=0']);

$result = $orders->queryBuilder()
    ->select('DocEntry,DocNum')
    ->find(123456); // DocEntry value

You can find more examples and the full documentation at https://syedhussim.com/sap-b1/php-sapb1-library-documentation-v1.html

php-sapb1's People

Contributors

syedhussim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-sapb1's Issues

Support for services and PUT requests

I've been using this library for almost a year now.
Since I'm working with the Picklists in SAP i was wondering if there could be support for

  • Services. eg. the [PickListsService_UpdateReleasedAllocation], the normal POST operation does not seem to work?
  • PUT requests. eg the [PUT][PickLists(id)]

According to the last one, the service Layer describes:
PickList is a very special object. The exposed properties are not enough for Service Layer to finish a patch operation with 'PickListsLines'. In this way, use 'put' instead.

Problem with SAPb1 Exception

Sorry, I'm a new user of the library and I've come across an Issue that apparently has already been resolved with an update, but it still doesn't work properly for me.

Do you have any advice I could use to make the library work?

Using PHP version 8.2.9

My code is the following:

$result = $orders->create([
"CardCode" => "C0005",
"DocDueDate" => "20230917",
"NumAtCard" => "TEST00001",
"Document lines"=> [
[
"Item code" => "10001_001_M6W8",
"Quantity" => 1,
"OcrCode" => "CRS"
]
]
]);

and the error it sends me is:

Warning: Try to read the property "value" into the string in phar://C:/inetpub/wwwroot/lib/sapb1.phar/SAPb1/SAPException.php on line 22

Fatal error: Uncaught SAPb1\SAPException in phar://C:/inetpub/wwwroot/lib/sapb1.phar/SAPb1/Service.php:44 Stack trace: #0 C:\inetpub\wwwroot\sl_Order.php(31): SAPb1\Service->create() #1 {main} thrown in phar://C:/inetpub/wwwroot/lib/sapb1.phar/SAPb1/Service .php on line 44

Allow retrieval of navigational properties and raw values in Query

Hi,
I've been enjoying working with this library, but I came against a limitation of the find method in the Query class which currently does not allow to:

  1. Retrieve a raw entity, like an image or a PDF attachment
    E.g. /Pictures('1234A.jpg')/$value
    E.g. /Attachments2(333)/$value
  2. Retrieve a navigational property
    E.g. /BusinessPartners('1234')/Invoices
  3. Retrieve a property raw value
    E.g. /Orders(1)/DocEntry/$value

While I understand that point 2 above can be worked around as /Invoices?$filter=CardCode eq '1234' and I don't have an actual use case for point 3 (it's mentioned in the documentation), point 1 seems pretty important when interacting with the service layer.

I've come up with a simple addition to the find method which is backwards-compatible.

public function find($id, string $property = '', bool $raw = false) : object|string{
    if(is_string($id)){
        $id = "'" . str_replace("'", "''", $id) . "'";
    }

    if($property) {
        $property = '/' . $property;
    }

    if($raw) {
        $property .= '/$value';
    }
    
    return $this->doRequest('(' . $id . ')' . $property);
}

However, the doRequest method currenly only returns a response if the content type is JSON or plain text. It needs to be patched in order to allow other content types such as images and pdfs:

private function doRequest(string $action = '', callable $callback = null){
    ...

    // Check if the response code is successful.
    if($response->getStatusCode() === 200){

        // If the Content Type is JSON, then get the body as an object.
        if ($response->getHeaders('Content-Type') == 'application/json'){
            $result = $response->getJson();
                
            ...
                
            // Return the result.
            return $result;
        }

        // If the Content Type is anything else (plain text, images, pdfs), then return the plain response body.
        else {
            return $response->getBody();
        }
    }
        
    // Throw an exception when the response code is not 200.
    throw new SAPException($response);
}

With the above changes, one could do the following:
$query->find( 333, '', '$value' ) or just $query->find( 333, '$value' ) and $query->find( '1234', 'Invoices' )

These changes should be safe in terms of backwards-compatibility, so I'm hoping this could be integrated in the library.
Thanks for your consideration.
Luca

Stock Transfer Example?

Hi, any chance you may have some PHP code examples for Stock Transfers? I saw your page mentioning them and the service layer, but I am mostly curious on the way the code would look using PHP. For example, I have the following, but there are syntax issues with it.:

$sap = new SAPClient($config, $session);
$InvTransfer = $sap->getService('StockTransfers');
$InvResults = $InvTransfer->create(
"FromWarehouse": "WH-A",
"StockTransferLines": [
{
"ItemCode": "12345",
"Quantity": "1",
"WarehouseCode" : "WH-B",
}
]

Can this approach be used? Also, is there a way to also include a "From-Bin" Location in addition to a "To-Bin" Location when doing these movements? All your examples just showed the goods moving to a destination bin, not so much moving from different source bins. Thanks much for any assistance you're able to provide.

Problem with SAPb1 Exception

Hello! I'm trying to use your project to test some functions of the Service Layer (much better than the Di Server) but I can't see the exceptions.. I get this error all the time:

Notice: Trying to get property 'value' of non-object in phar:///var/www/web/prod/php/service-layer/lib/sapb1.phar/SAPb1/SAPException.php on line 22

Fatal error: Uncaught SAPb1\SAPException in phar:///var/www/web/prod/php/service-layer/lib/sapb1.phar/SAPb1/Service.php:40 Stack trace: #0 /var/www/web/prod/php/service-layer/examples/set_document.php(31): SAPb1\Service->create(Array) #1 {main} thrown in phar:///var/www/web/prod/php/service-layer/lib/sapb1.phar/SAPb1/Service.php on line 40

I didn't change anything on the PHAR. and I'm using PHP 7.3, any idea?

Example Needed For Use With "SQLQueries" service

Hi, I'm hoping someone has an example they can share of how to use this library with the "SQLQueries" service inside of SAPB1. I was able to create a custom SQL Query using the following code:

$sap = new SAPClient($config, $session);
$sql = $sap->getService("SQLQueries");
	$qrySQL = $sql->create ( ["SqlCode"=>"sq104", 'SqlName'=> 'queryOnItem','SqlText' => 'select ItemCode, ItemName, from oitm'] );

Now I would like to display the results. The SAP Documentation states you must use the "/List" qualifier when calling the service, but I simply cannot get this to work. I went ahead and tried the following:

$myResults = $sap->getService("SQLQueries('sq104')\List");
$result = $myResults->queryBuilder()
    ->select('*')
    ->findall(); 
    echo '<pre>'; print_r($result); echo '</pre>';

But all that only shows me the details of the custom query:

stdClass Object
(
    [odata.metadata] => https://domain.com:50000/b1s/v1/$metadata#SQLQueries/@Element
    [SqlCode] => sq104
    [SqlName] => queryOnItem
    [SqlText] => select "ItemCode", "ItemName" from "OITM"
    [ParamList] => 
    [CreateDate] => 2023-10-18T00:00:00Z
    [UpdateDate] => 2023-10-18T00:00:00Z
)

What is the syntax to actually show me the resulting values of this query? Thanks in advance

Can't get it work :-(

I followed your guidelines but included the php file instead of the phar file.

The code runs until the first config will be instanced.

I have to include all used class files. My Server runs on PHP 7.3

Issue Updating DocumentLines inside Sales Order

Hi, I am hoping someone can point me in the right direction. I am trying to update specific line items on a Sales Order with a Country Code. I run my code and see a 1 (true) returned, thinking all is ok. However, SAP never actually gets updated. Running the (seemingly) same code inside of Postman works as expected. Can someone let me know what's incorrect with the code below? The data is fine, the apparent issue is with the update statement. I am guessing that I am not formatting it correctly. Appreciate any help!!

$results = $orders->update($DocEntry, ['DocumentLines' => ['LineNum' => $LineNum, 'CountryOrg' => "{$COO}"]]);

Pagination example required

Hi,

Due to restriction of 20 records per call, it would be greate if you share any example of pagination using next link?

Regards

How to include .phar file inside Functions.php of Wordpress

Hi, thanks very much for this library, but I am a bit stuck trying to make this work in conjunction with Wordpress and its functions.php file. I am trying to include your SAPb1.phar archive inside functions.php so I can pull some SAP data out, but when I do, the .phar file attempts to load all the other .php files Wordpress requires. Is there any workaround to this issue? Thanks in advance. This is what I see as an error msg:

failed to open stream: phar error: "xxxx/xxxx.php" is not a file in phar

SAPException issue with new ServiceLayer version

SAP changed the mapping for exceptions in the new service-layer version
I try to get some changelogs from SAP, but for so far no luck

Current version:
{ "error": { "code": -1000, "message": { "lang": "en-us", "value": "Property 'Remark' of 'InventoryCounting' is invalid" } } }

New version (10.00.210, Build: 11):
{ "error": { "code": "-1000", "details": [ { "code": "", "message": "" } ], "message": "Property 'Remark' of 'InventoryCounting' is invalid" } }

Can a skip method be added to the Query class?

Hi,
I understand why the Query method limit couples $top with optionally $skip.
However, I need to cycle through Items by using the $skip variable returned by the previous request (@odata.nextLink) without $top.

Unless I missed something, could I ask for a skip method to be added please?
Thanks,
Luca

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.