Skip to main content

Filtering Records

What are the filtering options available through the REST API?

Written by Petr Pech

Records in ABRA Flexi can be filtered. Filter values can be either direct – supported variable types, record identifiers, or placeholder values (e.g. now() or me()).

The list of supported attributes and their values (by type) can be obtained for each register in the field list.

Supported operators:

Operator

Name

Description

Example

= or == or eq

Equality

Operator equals the value

a = 1

<> or != or ne or neq

Inequality

Operator does not equal the value

a != 1

< or lt

Less than

a < 1

<= or lte

Less than or equal to

a <= 1

> or gt

Greater than

a > 1

>= or gte

Greater than or equal to

a >= 1

like

Contains

Record contains the string

a like 'inStr'

like similar

Contains regardless of diacritics

Record contains the string regardless of diacritical marks

a like similar 'inStr'

between

Is in range

vek between 18 100

begins

Starts with

a begins 'Win'

begins similar

Starts with regardless of diacritics

a begins similar 'Win'

ends

Ends with

a ends 'Strom'

in

Is a member of an enumeration

a in (1, 2, 3)

in subtree

Belongs to subtree

(see below)

in subtree 1

is true/false

Boolean comparison

a is true

is [not] null

Is (is not) filled in

a is null

is [not] empty

Is (is not) empty

not filled in or is zero/false/empty string

a is not empty

Operators from the similar group work correctly only on ABRA Flexi with a PostgreSQL 9.0 or newer database. With an older database version, these operators do distinguish diacritical marks, i.e. they behave the same as operators without the similar keyword.

Operator

Name

Description

Example

and

Logical AND operator

Allows combining conditions

a = 1 and b = 1

or

Logical OR operator

Allows combining conditions

a = 1 or b = 1

not

Logical NOT operator

Negates a condition

not a = 1

( )

Parentheses

(a = 1 or b = 1) and (c = 2)

Operators follow standard precedence: basic operators in the first table have the highest precedence, followed by not, and, and the or operator has the lowest precedence. If you are unsure, use parentheses.

The variant that negates is not null or ... is not supported, for example:

/faktura-vydana/(typDokl.typDoklK not like 'typDokladu.dobropis')

You must use the following variant, which returns the desired result:

/faktura-vydana/(not(typDokl.typDoklK eq 'typDokladu.dobropis'))

Variable

Name

Description

Example

now()

Current date and time

Allows displaying records relative to the current date.

datSplat < now()

currentYear()

Current year

Allows displaying records relative to the current year.

platiDo <= currentYear()

me()

Logged-in user name

Allows displaying records relative to the currently logged-in user.

uzivatel = me()

Filters must be properly URL-encoded. When building a filter manually, you can type it unencoded in the Firefox browser. When you copy it to the clipboard, Firefox will encode it automatically.

Writing values

In expressions such as a = 1, you can enter numbers, text strings, boolean values, dates, and date+time values. In addition, you can use the functions listed in the table above.

Numbers can be integers, -1 or 10, and decimals, 5.8 or -10.0.

Text strings can be enclosed in double quotes, "abc", or single quotes, 'abc'.

Boolean values are only true and false.

Dates are entered in the format YYYY-MM-DD, e.g. 2011-11-01, and date and time in the format YYYY-MM-DD'T'HH:MM:SS[.sss], e.g. 2011-11-01T12:30:00. Not all ISO 8601 notation variants are supported — only these two (or three) formats listed here.

When specifying a reference to an object, any identifier can be used. Internal IDs are written as numbers (firma = 1), while other identifiers are written as strings (firma = 'code:ABC').

Filtering by nested values

Some attributes used for filtering are actually relational references. For example, issued invoices can be filtered by customer as follows:

firma = 'code:FIRMA'

For these references, dot notation can also be used to filter by their attributes; for example, issued invoices can be filtered by the customer's group:

firma.skupFir = 'code:ODBĚRATEL-STANDARD'

The nesting depth is unlimited.

Note: for technical reasons, negative operators cannot be used (e.g. <>). In such cases, you will receive the error message OR logical subselect filter not supported.

Filtering by tags

In addition to attributes, you can filter by tags in the same way (if tags are supported in the given register). For example, if you want to find all price list items with the tag VIP, the filter will be:

stitky='code:VIP'

and the full URL will be

/c/firma/cenik/(stitky='code:VIP').xml

Or if you want all items with the tags VIP or DULEZITE, use:

stitky='code:VIP' or stitky='code:DULEZITE'

or alternatively

/c/firma/cenik/(stitky='code:VIP' or stitky='code:DULEZITE').xml

The and operator can be used in the same way.

Filtering by subtree membership

Price list items are organized in a tree structure (it may be possible in the future to organize items in a tree structure in other registers as well), and filtering by this classification is also supported. Consider the following price list tree:

Price list tree

  • Linked items (id = 2)

    • Category 1 (id = 3)

      • Category 1.1 (id = 4)

      • Category 1.2 (id = 5)

        • Category 1.2.1 (id = 6)

    • Category 2 (id = 7)

      • Category 2.1 (id = 8)

      • Category 2.2 (id = 9)

Unlinked items (a virtual node under which the application displays items that are not assigned to the tree; filtering within this node is not possible)

This is how the tree is displayed in the application; however, for the purposes of tree-based item categorization, we consider Linked items to be the root. The IDs shown are for illustration purposes only; when working with the tree via the REST API, it is recommended to use external identifiers.

On the price list (/c/firma/cenik), you can write a filter to retrieve all items from Category 1 and all its subcategories (i.e. from the nodes Category 1, Category 1.1, Category 1.2, and Category 1.2.1) as follows:

in subtree 3

which is essentially a shorthand notation for

id in subtree 3

The full URL would look like this:

/c/firma/cenik/(in subtree 3)

If you need to retrieve items only from a specific node and not from the entire subtree, you can use the nonrecursive modifier; for example, to retrieve items only from Category 2, but not from Category 2.1 or Category 2.2, you can write

in subtree 7 nonrecursive /c/firma/cenik/(in subtree 7 nonrecursive)

It was noted above that in subtree 3 is a shorthand for id in subtree 3, which is important when you need to filter other registers based on a price list item's subtree membership. For example, you can filter all stock cards for price list items from a specific subtree as follows:

cenik in subtree 3 /c/firma/skladova-karta/(cenik in subtree 3)

Filtering via relational properties

The filter allows arbitrary nesting depth, with the exception of properties that do not have a unique register. In other words, filtering is only possible for 1:1 relationships.

/udalost/(zakazka.mistUrc.mesto = 'Praha')

If you need to filter by document line items, you must filter directly in the line items register:

 /faktura-vydana-polozka/(doklFak=123 and cenik ="code:AUTO")

Default validity filter

All registers that have the platiOd and platiDo properties are filtered by the current accounting period by default. For example, if a price list has platiDo set to the value 2020, that price list will not appear in the cenik register if the current accounting period is 2021. This behavior can be suppressed using the filtrovat-platnost parameter set to the value false.

The following example shows how to retrieve price lists valid through the year 2020 in the current accounting period.

/c/firma/cenik/(platiDo = 2020).xml?filtrovat-platnost=false

User filters

The User Filters register is used for saving filters. To create a filter, you need to work with the fields of the /filtr register.

Example of creating a filter with a selected tag value:

<winstrom version="1.0">
<filtr>
<nazev>Stitky filtr</nazev>
<kod>stitky</kod>
<beanKey>cz.winstrom.vo.cen.Cenik</beanKey>
<obsahFiltru>((stitky = 3))</obsahFiltru>
</filtr>
</winstrom>

Example of filtering a register using a saved filter:

/c/firma/cenik/(filter:2)

Note: You must use the internal ID.

Did this answer your question?