# ERP5 Handbook/ERP5 Specific Zope tools

Generic description about ERP5 Specific Zope tools needs to be here.

## portal_activities

The idea of portal activities (aka CMF Activity Tool) is described in section:
Background process invocation - CMFActivity system
The way to use it is well described on the wiki:
http://wiki.erp5.org/HowToUseTheCmfActivityTool
The is little to add here, then.

## portal_catalog

Used to index objects, relations between objects, security information and some other frequently used data, to allow fast access, searching and sorting.
An object is recorded in catalog when you call .reindexObject on it. This method is called automatically upon every edit (technically, every setter - a method setThisProperty - triggers a reindex; if you write a script which is going to set many properties, better use _setThisProperty which does not reindex, and then call reindexObject; or even better call edit(property1 = value, property2 = value2) which reindexes once after setting all given properties).
Basic usage of portal_catalog is described here:
http://wiki.erp5.org/HowToSearchPortalCatalog
It is almost never needed to tweak catalog while implementing ERP5; some tricks are explained here:
http://wiki.erp5.org/HowToCreateRelatedKeys
http://wiki.erp5.org/HowToAddTableToCatalog

## portal_categories

The idea and use of categories is described in:
Categories
Base categories can be added with no restrictions (although it is always advisable to think for a moment, maybe one of the existing categories can do the job). Categories are indexed in MySQL; importantly, category memberships and relations between objects are also indexed, so the data model can be extended with little overhead.
Base category can be assigned to a portal type through property sheets, or simply through ZMI in portal_types tool. If an object has a given base category, it has all auto-generated accessors (setXXX, getXXX, setXXXList, getXXXlist).
Categories have a rich API; most heavily used methods are:
returns all subcategories recursively as pairs, suitable for filling a dropdown or ListField;
same, but translated;
returns all object which are classified to this category, or any of its direct or indirect subcategories (this includes subcatories themselves, but you can give it portal_type argument).
From the other end, every ERP5 object (a Person, for instance) has a method
which returns True if the object belongs to the given category OR to any of its direct or indirect subcategories. For example, if a Person has a function: "sales/retail/specialist", then
Base category has a rich user interface with many cryptic options, most of which refer to programmable acquisition which is explained here: http://wiki.erp5.org/HowToUseProgrammableAcquisition

## portal_contributions

This is a versatile tool which can devour (or ingest, if you prefer) almost anything you throw into it, guess what it is, find the right place to put it, analyze it and set various attributes of it.
More specifically: you call portal_contributions.newContent method, giving it some data (an uploaded file, for instance) or a url, optionally many other things (see the method's docstring, it is quite good). The tool then:
* uses WebDAV machinery to find out portal type for the content (it uses content_type_registry, so this is the place to set it up)
* calls ZMI scripts:
** [Type]_getPropertyDictFromFilename
** [Type]_getPropertyDictFromContent
to find out properties of the object, and if it gets any, sets them on the object; the scripts are type-based, so e.g. if the object is qualified as Spreadsheet, the tool looks for a script named "Spreadsheet_getPropertyDictFromFilename" and if not found, calls a generic one "Document_getPropertyDictFromFilename".
These scripts should return dicts of properties derived from file name and content; they can also return portal type, and this one will be eventually applied, so you can encode the content's type in its filename.
* finds out the right module to place the content in
* places the content in the right module
Contribution tool is used mostly by DMS module to ingest documents uploaded through web interface, sent in by email, or drag&dropped through WebDAV. In the nearest future it may be used also to receive and ingest emails.

## portal_rules

Generic description about portal_rules needs to be here.

### Invoice Transaction Rule

This rule is used by a builder to create Accounting Transaction Line after confirming Sale Invoice Transaction. You need to create a matrix of rules, which will be used to generate predefined Accounting Transaction Line.
If you need to define accounting system, this rule is what you need. Its definition will create proper accounting movements, based on predicates.
Begin in portal rules tool create new Invoice Transaction Rule, give it an Id and follow steps below for example based explanation.

#### Setting Predicates

After adding predicate you will be presented with a predicate screen. Set descriptive Title, which will be used as matrix column or row header. After setting Membership Criteria you will be able to set some Membership Values.
Predicates are grouped by a common Dimension, so set it carefully.
Keep in mind, that predicates may be constructed for some type of objects. In case of accounting you might want to create separate predicates for Sale and Purchase. To achieve it fill Test Method ID field with Movement_explanationPortalTypeIsPurchase for purchase patch and Movement_explanationPortalTypeIsSale for sale path.
When your matrix is ready, you can go and edit a template for Accounting Transaction Line. To test it, confirm Sale Invoice Transaction which is in planned state and observe how Accounting Transaction Line objects are created and filled.
Do not forget to fill Source and Destination views with proper accounts. Until then, system won't be able to generate proper simulations.

#### Full example

This example is taken for real world situation - traders in Poland. Requirement is to have defined region category, at least 3 different regions - Poland, Europe Union and Rest of The World. Example region tree is:
* region/africa
* region/asia
* region/europe
* region/europe/eu
* region/europe/eu/bg
* region/europe/eu/de
* region/europe/eu/fr
* region/europe/eu/ie
* region/europe/eu/pl (yes, it is Poland)
* region/europe/eu/uk
* region/europe/non-eu/ua
* region/north_america
* region/south_america
Create Predicates in your Invoice Transaction Rule:
* for purchase from Poland
** title: Purchase from Poland
** Dimension: region
** Test method ID: Movement_explanationPortalTypeIsPurchase
** Membership Criteria: source_region
** Membership Values: only source_region/europe/eu/pl
* for purchase from Europe Union
** title: Import from the Europe Union
** Dimension: region
** Test method ID: Movement_explanationPortalTypeIsPurchase
** Membership Criteria: source_region
** Membership Values: everything what is in source_region/europe/eu without source_region/europe/eu/pl and without source_region/europe/eu
* for purchase from rest of the world
** title: Import from outside of the Europe Union
** Dimension: region
** Test method ID: Movement_explanationPortalTypeIsPurchase
** Membership Criteria: source_region
** Membership Values: everything in source_region without source_region/europe/eu and below
* for sale into Poland
** title: Sale to Poland
** Dimension: region
** Test method ID: Movement_explanationPortalTypeIsSale
** Membership Criteria: destination_region
** Membership Values: destination_region/europe/eu/poland
* for sale to Europe Union
** title: Export to the Europe Union
** Dimension: region
** Test method ID: Movement_explanationPortalTypeIsSale
** Membership Criteria: destination_region
** Membership Values: everything what is in destination_region/europe/eu without destination_region/europe/eu/pl and without destination_region/europe/eu
* for sale to rest of the world
** title: Export to outside of the Europe Union
** Dimension: region
** Test method ID: Movement_explanationPortalTypeIsSale
** Membership Criteria: destination_region
** Membership Values: everything in destination_region without destination_region/europe/eu and below
Now play with created Accounting Rule Cell, then create some orders - sale and purchase, expand them (by ordering or planning) and check for simulations (e.g. by using Base_viewSimulationTree). Of course you may go further and create some invoices.
Beware: above configuration is for example purpose only.