/[erp5]/ERP5/PropertySheet/PropertySheets.stx
ViewVC logotype

Contents of /ERP5/PropertySheet/PropertySheets.stx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations) (download)
Mon Jan 13 11:12:26 2003 UTC (21 years, 3 months ago) by smets
Branch: MAIN
CVS Tags: HEAD
Branch point for: Modular
Changes since 1.4: +6 -0 lines
Updated with first Coramy working release

1 ERP systems involve many different attribute names which
2 can be used in different contexts. For example, a resource
3 may have a default global price. A path may define a default price
4 for specific source.
5
6 ERP5 uses PropertySheets in order to provide an explicit data model
7 which is used independently from interfaces. The role of interfaces
8 is to define common explicit behaviour which can be implemented through
9 by different classes. The role of property sheets is
10 to define common **attribute sets** which can be stored on instances
11 of different documents.
12
13 PropertySheets also hold explicit information about of the ERP data structure.
14 For example, some documents may not hold themselves pricing information
15 but rather acquire it through the order or the sourcing contract they depend from.
16
17 ERP5 implements this feature through **explicit acquisition**. The value
18 of attributes can be obtained by looking up the value of that attribute
19 on another related document or by calling a method on another related document.
20
21 Explicit acquisition requires to define relations between documents. The general
22 model adopted by ERP5 is a **categorization** model which is equivalent to
23 a DACG model (Direct Acyclic Colored Graph). Thanks to Zope acquisition, this model
24 is theoretically equivalent to a relationnal model.
25
26 We will explain bellow how those three concepts (attribute sets, categorization and
27 explicit acquisition) relate and how to define new Property Sheets in ERP5.
28
29 Attribute Sets
30
31 ERP5 uses Attribute Sets based on an approach which was originally developped
32 by Max M. for its Zope Easy Product (http://www.zope.org/Members/maxm/HowTo/easyProduct).
33 This approach consists in defining a set of attributes in the following way::
34
35 class Organisation:
36 """
37 Organisation properties and categories
38 """
39
40 _properties = (
41 { 'id' : 'corporate_name',
42 'description' : 'The official name of this organisation',
43 'type' : 'string',
44 'mode' : 'w' },
45 { 'id' : 'social_capital',
46 'description' : 'The social capital of this organisation',
47 'type' : 'int',
48 'mode' : 'w' },
49 { 'id' : 'social_capital_currency',
50 'description' : "The currency in which the social capital is"
51 "expressed",
52 'type' : 'string',
53 'mode' : 'w' },
54 )
55
56 The class *Organisation* is simply a place holder for an class attribute
57 called *_properties* which holds a list of dictionnaries, each of which
58 describes the *id*, the *purpose* and the *type* of an attribute. In the
59 above example, the attribute *corporate_name* is of type *string*, is
60 in *write mode* which means it can be read and modified and is described
61 as *The official name of this organisation*.
62
63 Attribute sets allow to group related attributes in a common *package*
64 and reuse them to define ERP5 classes. For example, the *Organisation* class
65 in ERP5 is defined as::
66
67 class Organisation(Entity, MetaNode, XMLObject):
68 """
69 An Organisation object holds the information about
70 an organisation (ex. a division in a company, a company,
71 a service in a public administration).
72
73 Organisation objects can contain Coordinate objects
74 (ex. Telephone, Url) as well a documents of various types.
75
76 Organisation objects can be synchronized accross multiple
77 sites.
78
79 Organisation objects inherit from the MetaNode base class
80 (one of the 5 base classes in the ERP5 universal business model)
81 """
82
83 meta_type = 'ERP5 Organisation'
84 portal_type = 'Organisation'
85 isPortalContent = 1
86 isRADContent = 1
87
88 # Declarative security
89 security = ClassSecurityInfo()
90 security.declareObjectProtected(ERP5Permissions.View)
91
92 # Declarative properties
93 property_sheets = ( PropertySheet.Base
94 , PropertySheet.XMLObject
95 , PropertySheet.CategoryCore
96 , PropertySheet.DublinCore
97 , PropertySheet.Organisation
98 )
99
100 # Factory Type Information
101 factory_type_information = \
102 { 'id' : portal_type
103 , 'meta_type' : meta_type
104 , 'description' : """\
105 An Organisation object holds the information about
106 an organisation (ex. a division in a company, a company,
107 a service in a public administration)."""
108 , 'icon' : 'organisation_icon.gif'
109 , 'product' : 'ERP5'
110 , 'factory' : 'addOrganisation'
111 , 'immediate_view' : 'organisation_edit'
112 , 'actions' :
113 ( { 'id' : 'view'
114 , 'name' : 'View'
115 , 'category' : 'object_view'
116 , 'action' : 'organisation_edit'
117 , 'permissions' : (
118 ERP5Permissions.View, )
119 }
120 , { 'id' : 'print'
121 , 'name' : 'Print'
122 , 'category' : 'object_print'
123 , 'action' : 'organisation_print'
124 , 'permissions' : (
125 ERP5Permissions.View, )
126 }
127 , { 'id' : 'metadata'
128 , 'name' : 'Metadata'
129 , 'category' : 'object_edit'
130 , 'action' : 'metadata_edit'
131 , 'permissions' : (
132 ERP5Permissions.View, )
133 }
134 , { 'id' : 'translate'
135 , 'name' : 'Translate'
136 , 'category' : 'object_action'
137 , 'action' : 'translation_template_view'
138 , 'permissions' : (
139 ERP5Permissions.TranslateContent, )
140 }
141 )
142 }
143
144 InitializeClass(Organisation)
145
146 The reader should take notice of two ERP5 specific features in the
147 class definition:
148
149 - the attribute *isRADContent* is set to 1, which is used by ERP5
150 to determine that a given class definition should be considered
151 as an **ERP5 RAD Class** or not. The meaning of *RAD* is *Rapid
152 Application Development*. Classes which set the
153 the attribute *isRADContent* to 1 will automatically benefit from
154 ERP5 RAD features (ex. automatic generation of accessors, automatic
155 generation of default values, etc.)
156
157 - the attribute *property_sheets* contains a list of PropertySheets. This
158 list defines the default attributes for all instances of the *Organisation*
159 class
160
161 During the initialization of an **ERP5 RAD Class**, the following
162 class attributes and methods will be automatically generated:
163
164 - a class attribute holding a **default value**. In
165 the example of the *Organisation* class, a class attribute
166 named *corporate_name* is created and set to
167 the default string ('').
168
169 - a default **getter** accessor method if no such accessor
170 is already defined by the class. In
171 the example of the *Organisation* class, a method
172 named *getCorporateName* is created, which returns
173 the value of the *corporate_name* instance attribute.
174
175 - a default **setter** accessor method if no such accessor
176 is already defined by the class. In
177 the example of the *Organisation* class, a method
178 named *setCorporateName* is created, which changes
179 the value of the *corporate_name* document attribute
180 and reindexes the document. Another method
181 named *_setCorporateName* is created to change
182 the value of the *corporate_name* document attribute
183 without reindexing it.
184
185 Besides *getters* and *setters*, all ERP5 documents
186 which are implemented by an **ERP5 RAD Class** can
187 be modified with the **edit** method. For example::
188
189 document.edit(corporate_name='ACME')
190
191 is equivalent to::
192
193 document.setCorporateName('ACME')
194
195 The use of *edit* allows to reindex documents only once.
196 For example::
197
198 document.edit(corporate_name='ACME',social_capital=30000)
199
200 is equivalent to::
201
202 document._setCorporateName('ACME')
203 document.setSocialCapital(30000)
204
205 Default attribute values and types are defined in the Utils.py
206 file at the root of the ERP5 Product::
207
208 defaults = {
209 'float' : 0.0,
210 'int' : 0,
211 'long' : 0L,
212 'date' : DateTime(),
213 'string' : '',
214 'text' : '',
215 'boolean' : 0,
216 'lines' : [],
217 'tokens' : [],
218 'selection' : [],
219 'multiple selection' : [],
220 }
221
222 **The use of getters and setters in ERP5 is not only recommended
223 but is considered as COMPULSORY** since they provide a functional
224 approach to content access and allow a more consistent implementation
225 of complex interactions between documents. **NEVER ACCESS DIRECTLY
226 A DOCUMENT ATTRIBUTE IN ERP5 OUTSIDE A PRIVATE METHOD.
227 ONLY USE GETTERS AND SETTERS**
228
229 *Implementation*: functions createDefaultAccessors and
230
231 Categories
232
233
234 First of all, a certain number
235 of base categories is defined. Such categories can are identified by a string such
236 as: region, client, skill, function, etc. Each category can hold subcategories,
237 sub-subcategories, etc. For example, regions allow to categorize geography in EPR5::
238
239 region/americas
240 region/americas/central
241 region/americas/north
242 region/americas/south
243 region/americas/south/brazil
244 region/europe
245 region/europe/central
246 region/europe/east
247 region/europe/north
248 region/europe/west
249 region/europe/west/france
250 region/europe/west/netherlands
251
252 (we only included the countries where people contribute to ERP5 currently - if you
253 contribute to ERP5 and your country is not list, let us know)
254
255 Each ERP5 document holds a *categories* attribute which contains a tuple
256 of category paths storever as a tuple of lines. Categories are considered
257 as a *slowly evolving* in an ERP5 system.
258
259 Documents which are implemented as **ERP5 RAD Class** can also benefit
260 from the automatic creation of accessors in the area of categories. For example,
261 the *Organisation* property sheet includes references to some default
262 base categories of ERP5::
263
264 class Organisation:
265 """
266 Organisation properties and categories
267 """
268
269 _properties = (
270 { 'id' : 'corporate_name',
271 'description' : 'The official name of this organisation',
272 'type' : 'string',
273 'mode' : 'w' },
274 { 'id' : 'social_capital',
275 'description' : 'The social capital of this organisation',
276 'type' : 'int',
277 'mode' : 'w' },
278 { 'id' : 'social_capital_currency',
279 'description' : "The currency in which the social capital is"
280 "expressed",
281 'type' : 'string',
282 'mode' : 'w' },
283 )
284
285 _categories = ( 'role', 'group', 'activity', 'skill', 'market_segment',
286 'social_form', 'function' )
287
288
289 The *_categories* attributes holds a tuple of strings which defines
290 which ids of base categories should be implemented by documents of
291 type Organisation. Based on this definition, the following getter and
292 setter methods are defined::
293
294 getRole getDefaultRole setRole _setRole
295 getGroup getDefaultGroup setGroup _setGroup
296 getActivity getDefaultActivity setActivity _setActivity
297 getSkill getDefaultSkill setSkill _setSkill
298 getMarketSegment getDefaultMarketSegment setMarketSegment _setMarketSegment
299 getSocialForm getDefaultSocialForm setSocialForm _setSocialForm
300 getFunction getDefaultFunction setFunction _setFunction
301
302
303 Each of these getters and setters sets or returns a list of partial path values except
304 for the *Default* category getter which returns the first value in of the base
305 category membership of a document.
306
307 Ordered Categories
308
309 Categories are ordered.
310
311
312 *Implementation*: all this is implemented by createCategoryAccessors
313 in Utils.py
314
315
316 Categories and relations
317
318 Categories allow to implement document categorization but also relations.
319 In ERP5, categories are managed by a portal tool names **portal_categories**.
320 Because ERP5 is based on Zope and because provides implicit acquisition,
321 if an EPR5 document has for example the following path::
322
323 /portal_root/organisation/3
324
325 Then, this object can also be accessed as::
326
327 /portal_root/portal_categories/client/organisation/3
328
329 This allows to define virtual categories in a base category
330 without having to create many subcategories. For example,
331 the category::
332
333 client/organisation/3
334
335 only exists through acquisition. Including in the list of category paths
336 of a document a paths such as::
337
338 client/organisation/3
339
340 is equivalent to creating an **arc** of coulor *client* between
341 that document and the document
342
343 /portal_root/organisation/3
344
345 Since relaltional models are equivalent to graphs, we can see
346 here that the ERP5 categorization model provides the same expressive
347 power as a relational model. Base categories are the equivalent
348 to a relation identifier. Arcs are created between a document
349 and a virtual subcategory acquired through implicit acquisition.
350
351 **All relations are therefore treated in ERP5 as categories**
352
353
354 Explicit Relational Acquisition
355
356
357 One of the purpose of property sheets is to create
358 a complete documentation of all attributes which can be used
359 in a complexe ERP5 system, and to make sure that no name conflict
360 happens. We want the *getTitle* or the *getPrice* accessor to mean the same thing
361 wherever it is used from.
362
363 In some cases, some attribute values can be *acquired* by one
364 document from another document. In the Zope environment,
365 acquisition allows to get the value of an attribute of one
366 document from the value of its parents. However, in ERP5,
367 we have multiple hierarchies. We may want to get the telephone
368 of a person based on the office he/she is working (which is a region
369 based tree) while we want to get the name of his product line
370 through the division he/she belongs to (this is a product line tree).
371
372 Explicit Relational Acquisition provides a simple way to implement
373 this feature. Let us look at the example bellow::
374
375
376 class SalesOpportunity:
377 """
378 Sales Opportunity properties and categories
379 """
380
381 _properties = (
382 { 'id' : 'client_organisation',
383 'description' : 'The organisation involved',
384 'type' : 'string',
385 'acquisition' : {
386 'base_category' : ('client',),
387 'portal_type' : ('Organisation',),
388 'copy_value' : 0,
389 'accessor_id' : 'getTitle',
390 'depends' : None
391 },
392 'mode' : 'w' },
393 { 'id' : 'client_person',
394 'description' : "The contact person involved",
395 'type' : 'string',
396 'acquisition' : {
397 'base_category' : ('client',),
398 'portal_type' : ('Person',),
399 'copy_value' : 0,
400 'accessor_id' : 'getTitle',
401 'depends' : None
402 },
403 'mode' : 'w' },
404 )
405
406 _categories = ('role', 'group', 'activity', 'function',
407 'social_form', 'skill', 'market_segment')
408
409
410 The name of the client_person is acquired by look at documents
411 of type *Person* in the *client* tree (or relation) and applying
412 the getTitle method. The attribute can be calculated each time
413 (copy_value is 0) or copied once for all (copy_value is 0).
414
415 Accessors:
416
417 _getReference
418 _getReferencePath
419 _getReferenceList
420
421
422 FAQ
423
424 Do I need to create an attribute for a category ?
425
426 It depends : if some information can be in a different application,
427 you need to holde the information somewhere, ....
428
429 Possible scenario
430
431 copy_value
432 mask_value
433 sync_value
434
435
436 Future
437
438 Atribute lookup should be put outside property sheet
439 into a tool ?

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26