oliverbj/cord

Seamless integration to CargoWise One's eAdapter using the HTTP service.

2.0.1 2023-06-20 12:41 UTC

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Cord offers a expressive, chainable and easy API to interact with CargoWise One's eAdapter using their HTTP Webservice.

Installation

You can install the package via composer:

composer require oliverbj/cord

You can publish the config file with:

php artisan vendor:publish --tag="cord-config"

This is the contents of the published config file:

return [
    'eadapter_connection' => [
        'url' => env('CORD_URL', ''),
        'username' => env('CORD_USERNAME', ''),
        'password' => env('CORD_PASSWORD', ''),
    ],
];

Usage

Setting environment

In order to use Cord, you must specify the appropiate login details for your CargoWise One eAdapter service:

CORD_URL=
CORD_USERNAME=
CORD_PASSWORD=

Modules

Cord comes with connectivity to the following modules:

  • Bookings booking()
  • Shipments shipment()
  • Customs custom()
  • Organizations organization()
  • Companies company()

Similar for all, you must call the run() method to 'get' the actual response back from the eAdapter. The response from the eAdapter will be returned in a JSON format.

//Get a shipment
Cord::shipment('SMIA12345678')
    ->run();

//Get a brokerage job
Cord::custom('BATL12345678')
    ->run();

//Get an organization
Cord::organization('SAGFURHEL')
    ->run();

//Get a company
Cord::company('CPH')
    ->run();

Organizations - Add Address

Cord supports the option to add an address to an organization.

Cord::organization('SAGFURHEL')
        ->addAddress([
            'code' => 'MAIN STREET NO. 1',
            'addressOne' => 'Main Street',
            'addressTwo' => 'Number One',
            'country' => 'US',
            'city' => 'Anytown',
            'state' => 'NY',
            'postcode' => '12345',
            'relatedPort' => 'USNYC',
            'capabilities' => [
                'AddressType' => 'OFC',
                'IsMainAddress' => 'false',
            ]
        ]);

Documents / eDocs

Most entities in CargoWise One have a document tab (called eDocs). It is possible to use Cord to access these documents using the withDocuments() method. When applying the documents method, Cord will only a DcoumentCollection containing the documents from the specified entity.

//Get all the available documents from a shipment file
Cord::shipment('SMIA12345678')
    ->withDocuments()
    ->run();

When interacting with the eDocs of CargoWise One (getting documents), we can provide filters to the request:

//Get only documents from a shipment file that is the type "ARN"
Cord::shipment('SMIA92838292')
    ->withDocuments()
    ->filter('DocumentType', 'ARN')
    ->filter('IsPublished', True)
    ->run();

The available filters are:

  • DocumentType – Retrieve only documents matching the specified document type.
  • IsPublished – Retrieve only published or un-published documents. The values for this filter are: True and False. This can only be specified once.
  • SaveDateUTCFrom – Retrieve only documents that were added or modified on or after the specified date/time (provided in UTC time). This can only be specified once.
  • SaveDateUTCTo – Retrieve only documents that were added or modified on or before the specified date/time (provided in UTC time). This can only be specified once.
  • CompanyCode – Retrieve only documents related to the specified company or non-company specific. The default behavior without this Type being filtered is to return all documents regardless of company affiliation.
  • BranchCode – Retrieve only documents related to the specified branch code.
  • DepartmentCode – Retrieve only documents relevant to specified department code.

Upload Documents

Similar to fetching documents, it is also possible to upload documents to a file in CargoWise One using addDocument:

Cord::shipment('SJFK21060014')
        ->addDocument(
            file_contents: base64_decode(file_get_contents("myfile.pdf")),
            name: 'myfile.pdf',
            type: 'MSC'
            description: '(Optional)',
            isPublished: true //default is *false*
        )
        ->run();

Cord also supports interacting with CargoWise One's event engine, meaning we can add events to jobs:

Cord::shipment('SJFK21060014')
        ->addEvent(
            date: date('c'),
            type: 'DIM',
            reference: 'My Reference',
            isEstimate: true //default is *false*
        )
        ->run();

Native Query Component

You can query all supported native query components that eAdaptor provides. Similar to all native query components is that you can run the criteriaGroup() method, to "query" your results.

Example: When querying organizations, you can specify different criteria groups to filter the results using criteriaGroup():

Cord::organization()
        ->criteriaGroup([
            [
                'Entity' => 'OrgHeader',
                'FieldName' => 'Code',
                'Value' => 'US%'
            ],
            [
                'Entity' => 'OrgHeader',
                'FieldName' => 'IsBroker',
                'Value' => 'True'
            ],
        ], type: "Partial")
        ->run();

The criteriaGroup() method accepts a nested array of different criteria. The above will search for all organizations where the organization code starts with US and the organization is a broker. The type parameter can be either Partial or Key. The default is Key.

The XML that is generated by the above code is:

<Native xmlns="http://www.cargowise.com/Schemas/Native">
   <Body>
      <Organization>
         <CriteriaGroup Type="Partial">
            <Criteria Entity="OrgHeader" FieldName="Code">US%</Criteria>
            <Criteria Entity="OrgHeader" FieldName="IsBroker">True</Criteria>
         </CriteriaGroup>
      </Organization>
   </Body>
</Native>

You are free to define as many criteria groups as you want:

Cord::organization()
        ->criteriaGroup([
            [
                'Entity' => 'OrgHeader',
                'FieldName' => 'Code',
                'Value' => 'US%'
            ],
        ], type: "Partial")
        ->criteriaGroup([
            [
                'Entity' => 'OrgHeader',
                'FieldName' => 'IsBroker',
                'Value' => 'True'
            ],
        ], type: "Partial")
        ->run();

Info: Multiple criteria group acts as an "OR" statement.

The above with multiple criteria groups will generate the following XML:

<Native xmlns="http://www.cargowise.com/Schemas/Native">
   <Body>
      <Organization>
         <CriteriaGroup Type="Partial">
            <Criteria Entity="OrgHeader" FieldName="Code">US%</Criteria>
         </CriteriaGroup>
         <CriteriaGroup Type="Partial">
            <Criteria Entity="OrgHeader" FieldName="IsBroker">True</Criteria>
         </CriteriaGroup>
      </Organization>
   </Body>
</Native>

Multiple Connections

Sometimes you may want to connect to multiple eAdapters. This can be done by using the withConfig method:

$config = "my_custom_connection";
Cord::shipment('SJFK21060014')
      ->withConfig($config)
      ->run();

Then you can add the connection details to your config/cord.php file:

return [
    'base' => [
        'eadapter_connection' => [
            'url' => env('CORD_URL', ''),
            'username' => env('CORD_USERNAME', ''),
            'password' => env('CORD_PASSWORD', ''),
        ],
    ],

    'my_custom_connection' => [
        'eadapter_connection' => [
            'url' => env('CORD_URL', ''),
            'username' => env('CORD_USERNAME', ''),
            'password' => env('CORD_PASSWORD', ''),
        ],
    ],
];

The URL does not neccessarily need to be directly to the eAdaptor URL. It can also point to a middleware, as long as the middleware forwards the request to the eAdaptor and returns the response.

Response as XML

If you want to return the original eAdaptor response directly as XML, call toXml() before you call the run() method:

Cord::shipment('SJFK21041242')->toXml()->run();

Debugging

Sometimes you may want to inspect the XML request before it's sent to the eAdapter. To do this, you can simply call the inspect() method. This will return the XML string repesentation:

$xml = Cord::custom('BJFK21041242')
            ->documents()
            ->filter('DocumentType', 'ARN')
            ->inspect();

return response($xml, 200, ['Content-Type' => 'application/xml']);

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.