Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

762 Commits

Repository files navigation

PHP AbraFlexi

PHP AbraFlexi Logo

PHP 8.1+ based library for easy interaction with the Czech economic system AbraFlexi.

Latest VersionSoftware LicenseGitHub forkswakatimePackagist Version

Latest Stable VersionTotal DownloadsLatest Unstable VersionLicenseMonthly DownloadsDaily Downloads

Acknowledgements

The creation of this library would not have been possible without the kind support of Spoje.Net 👍

Spoje.Net

Special thanks to the technical support of ABRA Flexi s.r.o. for their patience in responding to all questions and bug reports.

Installation

composer require spojenete/abraflexi

so that your resulting composer.json contains:

{
"require": {
"spojenet/abraflexi": "^3.7"
}
}

Run the installation with the command composer install:

Configuration

Configuration is done by setting the following constants:

// AbraFlexi API URLdefine('ABRAFLEXI_URL', 'https://abraflexi-dev.spoje.net:5434');
// AbraFlexi API Userdefine('ABRAFLEXI_LOGIN', 'apiuser');
// AbraFlexi API Passworddefine('ABRAFLEXI_PASSWORD', 'apipass');
// Company in AbraFlexidefine('ABRAFLEXI_COMPANY', 'test_s_r_o_');
// Or if you do not want to use username and passworddefine('ABRAFLEXI_AUTHSESSID', '6QuifebMits'); // Optional// Slow server, large database, and over a modemdefine('ABRAFLEXI_TIMEOUT', 60); // Optional// Return PHP exception if AbraFlexi returns an errordefine('ABRAFLEXI_EXCEPTIONS', true); // Optional

If the constants are not set, the classes will also try to configure themselves from environment variables of the same name, e.g. getenv('ABRAFLEXI_URL')

It is also possible to provide login credentials when creating an instance of the class.

$invoicer = new \AbraFlexi\FakturaVydana(null,[
'company' => 'Firma_s_r_o_',
'url' => 'https://abraflexi.firma.cz/',
'user' => 'rest',
'password' => '-dj3x21xaA_'
]);

This method of setting has a higher priority than the above constant definitions.

$order = new \AbraFlexi\ObjednavkaPrijata('code:OBP0034/2019',['companyUrl'=> $_GET['companyUrl'], 'authSessionId'=>$_GET['authSessionId'] ])

In this way, an application triggered by a user button passing the values companyUrl and authSessionId can connect to abraflexi and a specific order.

How does it all work?

The central component of the entire library is the RO class, which is able to communicate with the AbraFlexi REST API using the PHP curl extension.

From it, classes for individual records are derived, containing methods for frequently used operations, for example "Pay" in the case of received invoices.

A new derived class is created so that the class name is the name of the record but without hyphens. These are replaced by capital letters in the name.

functionevidenceToClass($evidence)
{
returnstr_replace('', '', ucwords(str_replace('-', '', $evidence)));
}

So, if we want to derive a new class for the record "Měrné jednotky" (Units of Measure), it will look like this:

<?php/** * @link https://demo.abraflexi.eu/c/demo/merna-jednotka/properties Properties of the record */class MernaJednotka extends /AbraFlexi/RW
{
/** * Record used by the object. * * @var string */public$evidence = 'merna-jednotka';
}

And then it is easy to list the units of measure in 2 lines:

$jednotky = newMernaJednotka();
print_r( $jednotky->getAllFromAbraFlexi() );

If we want the newly created class to be able to write to abraflexi, it must be derived from the AbraFlexiRW parent.

More usage examples can be found in a separate project

Structure of Records, Actions, and Relations

In some cases, it is good to know what actions can be performed or what the structure of a record is. This information can be obtained by calling https://demo.abraflexi.eu/c/demo/*/properties.json or https://demo.abraflexi.eu/c/demo/*/actions.json. However, these are relatively time-consuming operations. Since the structure of records and actions or relations between records in AbraFlexi does not change often, AbraFlexi has a mechanism that allows you to work with this data without having to query the server.

The structure is stored in the Structure class (Actions, Relations), which contains a statically defined array with information that would otherwise have to be obtained from AbraFlexi.

An item in the list of records https://demo.abraflexi.eu/c/demo/evidence-list can then be easily displayed at any time:

echo \AbraFlexi\Structure::$evidence['faktura-vydana'];

The structures of individual records are then stored in static variables. Their name follows the same rules as for creating a new class name, except that the first letter is lowercase.

lcfirst(\AbraFlexi\Functions::evidenceToClassName($evidence))

If necessary, these classes can then be generated with the current content using the following command:

cd tools/
./update_all.sh

The operation takes several minutes. You can view the progress as follows:

tail -f /var/log/syslog | grep AbraFlexitest

Debug mode

If you set $this->debug to true in AbraFlexi objects, additional tests will be performed before sending data to AbraFlexi. The following possible errors are checked:

  • Does the inserted field exist for the record?
  • Is the inserted field read-only?
  • If the inserted field is a relation, is it also a field?

In debug mode, all requests to abraflexi and their responses are also saved to the /tmp folder

The library includes a mechanism for sending recorded errors during AbraFlexi runtime to developers:

If AbraFlexi returns Internal Server Error 500, an email containing the error message is sent to the developers.

If AbraFlexi is running on the same server and it is possible to read the error logs, the appropriate fragment is extracted from them and added to the body of the email.

The email also contains additional information about the license and enabled modules.

Attachments also include files containing the body of the request to the server, the body of its response, and a file containing information about curl.

During the life of the object, errors are recorded and only the first of each kind is sent.

Changes in version 3.6

  • Default curl timeout set to 300
  • Maximized use of the Relation object
  • New class AbraFlexi\Code replacing Functions::code and Functions::uncode
  • Classes are available for all records (not just the frequently used ones)

Changes in version 3.7

  • Enhanced code generation tools for evidence classes
  • Improved error handling and exception management
  • Added comprehensive PHPUnit test coverage for new classes
  • Enhanced internationalization support with English translations

Example of creating an instance of the FakturaVydana class

The default Native types mean that from the server, in a field containing a date, you get a PHP DateTime object. In the 'id' column, an integer, etc. This behavior can be disabled using the constructor parameter ['nativeTypes' = false]

new \AbraFlexi\FakturaVydana( 'code:VF2-12345', ['nativeTypes'=>false,'debug'=>true,'ignore404'=>false] );

See: constructor RO

You can specify some of these parameters:

 * user, password, authSessionId - authentication
* company, url, evidence - force access parameters
* prefix - for URLs starting differently than '/c/' for company
* defaultUrlParams - array of properties then automatically added
* debug - to enable debug mode
* detail - to specify the required [level of detail](https://www.flexibee.eu/api/dokumentace/ref/detail-levels/).
* offline - no network operations are performed (do not connect when instantiating the object)
* filter - see [Filtering](https://www.flexibee.eu/api/dokumentace/ref/filters}
* ignore404 - if you do not know whether the requested record exists, set to true so it does not throw an error
* nativeTypes - if you want everything from the server to be returned as strings
* timeout - patience before a network communication error is thrown (passed to cURL)
* companyUrl - loads all connection details from the string (API password, etc.)
* ver - force API version (if you want to call functions intended for the new web interface)
* throwException - throw an exception at every suitable opportunity

Autoloading data

If the constructor of the object is given an ID of type int or a code (code:..) of the record, it calls the function loadFromAbraFlexi(id). Then it is possible to access the loaded values using the methods $this->getData() and RO::getDataValue('name')

Data types

Machine NameNameNoteExamplePHP Type
stringStringEncoding is unicode. Any character can be used.crazy pony こちらは田中さんですstring
integerIntegerMust be without spaces. It is a signed 4-byte integer, but the range may be limited (see the overview of items for the given record)12integer
numericDecimal numberMust be without spaces, the decimal separator is a dot. It is an 8-byte double, but the range may be limited (see the overview of items for the given record)12.5float
dateDateDate in the format YYYY-MM-DD; you can also specify a time zone (YYYY-MM-DDZZZ), but it will be ignored. ZZZ is the time zone designation (Z or +HH:MM or -HH:MM).1980‑05‑06 2015‑01‑30Z 2008‑09‑01+02:00\Date()
datetimeDate + timeDate and time in the format YYYY-MM-DD'T'HH:MM:SS.SSS; you can also specify a time zone (YYYY-MM-DD'T'HH:MM:SS.SSSZZZ), but it will be ignored.1980‑05‑06 1980‑05‑06T12:30:12 2015‑01‑30T22:55:33Z 2008‑09‑01T17:18:14+02:00 2008‑09‑01T17:18:14.075+02:00\DateTime()
logicBoolean valuebooleantrue falseboolean
selectSelect one valueSelect one value. It is represented as a string.typVztahu.odberDodavstring
relationData relationThe input is a record from another evidence (overview of identifier types)123 code:CZK ext:DB:232\AbraFlexi\Relation

Testing

PHPUnit tests are located in the testing folder. If you want to test against a different server than the official http://demo.abraflexi.eu/, you need to change the settings in the bootstrap.php file.

The contents of the $testServer variable determine which of the preset settings will be used. And of course, you can define your own. As an example, the test server spoje.net is given here.

For testing, please first create a test company TESTING s.r.o. and set the access data for a user authorized to use the REST API. (Which is the administrator user specified during the installation of AbraFlexi.)

Warning: testing against a company with many invoices and a connected bank may take some time, as automatic document matching is also tested.

If you decide to inherit AbraFlexi in your project and write tests for these classes also inherited from AbraFlexi, e.g.:

class HookRecieverTest extends \Test\AbraFlexi\ChangesTest

Add the paths to the original tests to your composer.json:

"autoload-dev": {
"psr-4": {
"Test\\": "vendor/spojenet/php-abraflexi/test/src/AbraFlexi/test/",
"Test\\Ease\\": "vendor/vitexsoftware/ease-core/tests/src/Ease",
"Test\\AbraFlexi\\": "vendor/spojenet/php-abraflexi/test/src/AbraFlexi/",
}
}

Examples

In the Examples folder, you can find these usage examples:

FileDescription
AttachmentSaveToFile.phpsave attachment to file
AttachmentUpload.phpupload attachment
AuthSessionIdUsage.phpExample of AuthSessionId authentication
AuthentizeContact.phpcontact authentication
BatchOperation.phpUsing filter in batch operations
CreateLabel.phpworking with labels
DryRun.phpTest save (dry-run)
DownloadInvoicePDF.phpdownload invoice PDF
Error404.phpworking with non-existent records
FindOverdueInvoices.phpfind overdue invoices
GetRecordWithRelation.phpGet record including data from sub-record
GetBankAccountForCompany.phpGet bank account for company from directory
InvoiceLockUnlock.phpLocking and unlocking record
InvoiceCopy.phpcreate tax document from advance
LoginLogoutuser login and logout
NajdiDanovyDokladKzalohovemu.phpfind document
Naskladnění.phpStock product with serial numbers
NewInvoice.phpNew invoice with due date printed as json
ObjectChaining.phpChaining objects for multiple operations in one request
ObjectCooperation.phpSharing data and connection parameters between objects
PerformingActions.phpHow to perform actions on a document, e.g. cancellation
ReadAddressColumns.phpreturn specific columns
sendInvoiceByMail.phpsend invoice by email
SendReminders.phpsend reminders
SetContactAuth.phpset authentication
TestConnection.phpconnection check

Usage examples

References

AbraFlexi libraries for other languages

WakaTime project statistics

About

PHP Library for easy interaction with economic system AbraFlexi.

Topics

Resources

Code of conduct

Contributing

Stars

24 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages