========= Task tree ========= All objects of the framework represent a tree of objects. These object are called items. All items of the tree have common ancestor class ``AbstractItem`` ( :doc:`client reference ` / :doc:`server reference ` ) and common attributes:. * ``ID`` - unique in the framework ID of the item * ``owner`` - immediate parent and owner of the item * ``task`` - root of the task tree * ``items`` - list of child items * ``item_type`` - type of the item * ``item_name`` - the name of the item that will be used in programming code to get access to the item * ``item_caption`` - the item name that appears to users At the root of the tree is the task item. The task contains group items. There are three types of groups that have the following values of the ``item_type`` attribute: * "items" - these groups contain items with "item" ``item_type``, that can have associated database table. * "details" - such groups also contain items that can have associated database tables, but they can be used to create details for other items (see :doc:`Details ` ). * "reports" - these groups contain reports - items with "report" ``item_type``, that are used to create reports. You can create your own groups. Items that can have associated database table can own details, that are used to store records that belong to a record of the master. For example the task tree of the :doc:`Demo project ` is:: /demo/ catalogs/ customers tracks albums artists genres media_types journals/ invoices/ invoice_table details/ invoice_table reports/ invoice purchases_report customers_report At the root of the task tree is a task with the ``item_name`` **demo**. It has four groups: **catalogs**, **journals**, **details** and **reports**. The **catalogs**, **journals** groups have ``item_type`` "items". The items they own are wrappers over the corresponding database tables. There is one detail item with ``item_name`` **invoice_table**, that also has it's own database table, and three reports in the **reports** group. The **invoices** journal has the **invoice_table** detail, which keeps a list of tracks in an customer's invoice. So there are two items with the same name "invoice_table" (detail_item and detail). They share the same database table. Every item is an attribute of its owner and all items, tables and reports are attributes the task as well (they all have a unique ``item_name``). A task is a global object on the client. To access it, just type ``task`` anywhere in the code. On the server, the task is not global. Jam.py is an event-driven environment. Each event has as a parameter the item (or field) that triggered the event. Functions defined in the server module of an item that can be executed from the client module using the :doc:`server ` method have the corresponding item as the first parameter as well. Knowing an item, we can access any other item of the task tree. For example to get access to the **customers** catalog we can write .. code-block:: js def on_apply(item, delta, params): customers = item.task.catalogs.customers.copy() or just .. code-block:: js def on_apply(item, delta, params): customers = item.task.customers.copy() The hierarchical structure of the project is one of the bases of the DRY (don't repeat yourself) principle of the framework. For example, some methods of the items, when executed, successively generate events for the task, group and the item. This way we can define a basic behavior for all items in the event handler of the task, that can be expanded in the event handler of the group, and finally, if necessary, can be specified in the event handler of the item itself. For more details see :doc:`Form events ` Video ===== The `Task tree`_ video tutorial demonstrates the task tree using :doc:`Demo project ` .. _`Task tree`: https://youtu.be/hsSKqEh6vL4