need urgent help on architecture

Asked by Cuong

Hi,

I need to manage different kinds of products. Each product type has different properties, for example
- LCD: panel size in inches, CRT/LCD/LED, brightness,...
- CPU: cache, frequency, number of cores, type (pentium, core i, xeon,..)
- Mainboard: socket type, number of USB port, VGA integrated or not,...
- Mouse: ...
- Keyboard: ....
- Case: ....
- Disk drive: ....
- Power supply: ....
- Sound card: ....
- Network card: ...
- Wifi card: ...
- USB drive: ...
- and many more

We have base class product.product. We can inherit this class for these product types. However, the issue is how to manage these types of product in only one view.

Why? If we make a menu for each type, then there will be a lot of menus (in case we have several hundreds of product types, or even we have tens of thousands of animal kinds if we need to manage animals).

So how can we solve this? I want to do this
1. In product form view, I can choose product type, then edit/modify its properties
2. In tree view, I can display properties depending on product type. For ex, with CPU I will display frequency, number of core, CPU types,..; with monitor I will display panel size,...

Each product type will has its own table. Maybe product_monitor for monitor, product_cpu for CPU, product_mainboard for Mainboard,...

Thank you very much,

Question information

Language:
English Edit question
Status:
Answered
For:
Odoo Server (MOVED TO GITHUB) Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Ferdinand (office-chricar) said :
#1

We can develop a solution for you

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) said :
#2

@Ferdinand I bet a lot of people who read OpenERP Questions could post that answer to a lot of questions ;-)

Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) said :
#3

Hello,

I would suggest taking a look at the V6.0 and trunk version of
magentoerpconnect https://code.launchpad.net/magentoerpconnect
We still define one menu by type of product, but we could actually remove it
(and we will) as there is now a new wizard (inside the product form)
enabling to edit the specific product fields according to the product type.
Also, in trunk we avoid creating all specific product fields as new columns
and instead map the optional fields into a single json text column. The
exact implementation of it is however going to evolve a bit until version
6.1. Hope this helps.

On Mon, Aug 1, 2011 at 2:15 PM, Stefan Rijnhart (Therp) <
<email address hidden>> wrote:

> Question #166633 on OpenERP Server changed:
> https://answers.launchpad.net/openobject-server/+question/166633
>
> Stefan Rijnhart (Therp) posted a new comment:
> @Ferdinand I bet a lot of people who read OpenERP Questions could post
> that answer to a lot of questions ;-)
>
> --
> You received this question notification because you are a member of
> OpenERP Committers, which is an answer contact for OpenERP Server.
>

Revision history for this message
Stefan Rijnhart (Opener) (stefan-opener) said :
#4

Cuong, after spamming your question, let me try to give you some direction. I think in a custom tree view of product types you may be able to associate a custom action to perform when a record is opened. At least you should be able to create a method that presents another tree view with all products of that type (of course, use a domain for that) with a reference to the form and search view of that specific type, and add a button to the product type tree view to call that method. This way all products are in the same table but you will have hundreds of views for the same model.

You can also browse a list of all products, and try to present a different view for each type of product. You can do so by overriding fields_view_get() of the product_product model, based on the active_id from the context. Be sure to disable the view caching in the web client. If you want to escape this performance impact, keep the caching and hack the client so as to request a view id for each product id (and hack your model to provide it).

Good luck! If your head explodes, call me or Ferdinand ;-)

Stefan.

Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) said :
#5

he issue with overriding fields_view get, is that it will work only for a
given context that will remain the same in all the collection of a given
menu.
This is the old way we did in magentoerpconnect. This is why we now suggest
the wizard intermediary button as I suggested, this is the only way today to
have a different view in the same menu as OpenERP will cache the main view
for the whole menu.

On Mon, Aug 1, 2011 at 2:41 PM, Stefan Rijnhart (Therp) <
<email address hidden>> wrote:

> Question #166633 on OpenERP Server changed:
> https://answers.launchpad.net/openobject-server/+question/166633
>
> Stefan Rijnhart (Therp) proposed the following answer:
> Cuong, after spamming your question, let me try to give you some
> direction. I think in a custom tree view of product types you may be
> able to associate a custom action to perform when a record is opened. At
> least you should be able to create a method that presents another tree
> view with all products of that type (of course, use a domain for that)
> with a reference to the form and search view of that specific type, and
> add a button to the product type tree view to call that method. This way
> all products are in the same table but you will have hundreds of views
> for the same model.
>
> You can also browse a list of all products, and try to present a
> different view for each type of product. You can do so by overriding
> fields_view_get() of the product_product model, based on the active_id
> from the context. Be sure to disable the view caching in the web client.
> If you want to escape this performance impact, keep the caching and hack
> the client so as to request a view id for each product id (and hack your
> model to provide it).
>
> Good luck! If your head explodes, call me or Ferdinand ;-)
>
> Stefan.
>
> --
> You received this question notification because you are a member of
> OpenERP Committers, which is an answer contact for OpenERP Server.
>

Revision history for this message
Cuong (bhcuong2008) said :
#6

Thank all of you for suggestion.

After a week of investigating this, together with your suggestion, I think that using wizard form is simpler than hacking fields_view_get in this case as suggested by Raphael. I will refer to magentoconnect for detail implementation.

I dont know whether magentoconnect uses separate table for each product type or the same table product_product. I prefer to use each table per class in generalization/specialization data modeling. Also I like to use delegation inheritance in OpenERP.

So if I make a class, named 'product.lcd' inherited from 'product.product', using delegation inheritance, then when I open a wizard to edit this class, it will make another record in 'product.product', different from the one I'm editing.

Take an example, I open product form, make a new product lcd_01 of typ lcd, then click on 'Property' button to pop up a wizard for editing properties of lcd_01. Because lcd class is inherited from product, OpenERP will automatically create anther record in table product_product. So how can we avoid this while still using delegation inheritance. Using delegation inheritance, we can easily access attributes when programming such as lcd_01.name, lcd_01.price,...In principal, Delegation inheritance uses foreign key referencing to product_product table. With traditional way we use like this, lcd_01.product_id.name, lcd_01.product_id.price,...

But in tree/search view, how can we solve this problem, means displaying different content depending on product types. Take an example, user choose LCD type, it must display properties of lcd type in tree/search view or when choosing CPU type, it will hide LCD properties, display CPU properties.

I imagine that in search view we have a field (widget="selection") showing all product types. When user chooses CPU type, in tree view it will add/remove some columns for this type.

Because we are using a table per class, we can't use traditional way using 'attrs'. In tree view of product.product, we can't add <field name="frequency"/>,...OpenERP can't understand 'frequency' and it will report error.

So I wonder whether I can use fields_view_get to solve this. We will make tree view for each product type. Then we catch field product_type in search view, and generate tree view for each product type on-the-fly. But fields_view_get is called only one time when we click on menu. Up to now, I think we can't use this way.

Please teach me details.

Thank you very much,

Revision history for this message
Ferdinand (office-chricar) said :
#7

may be another idea

create a o2m table for product categories like LCD, mouse, keyboard with the necessary attributes + optional/mandatory, it's also possible to define a field with some check conditions for each individual attribute to avoid wrong data entry

for products
* create a o2m table with is automatically populated with the attributes from the category, + a field which holds the value
* create a function field which reads these attributes in on line to allow easy printing

this also allows to add new attributes to categories later

hope that helps

Revision history for this message
Cuong (bhcuong2008) said :
#8

Hi Ferdinand,

As your suggestion, I understand as following:
1. create a class, called 'product.class' (product type), consists of 2 fields
class product_class(osv.osv):
   _columns = {
      'name': fields.char, => category name: LCD, CPU, Mainboard,...
      'attr_ids': fields.one2many('product.attribute', 'class_id') => point to list of properties
   }
class product_attr(osv.osv):
   _columns = {
      'name': fields.char,
      'value': fields.,
      'class_id': fields.many2one('product.class')
   }

2. next, in product.product, create a many2one field to product.class. Also, create a related field of type one2many
class product(osv.osv):
   _columns = {
      'class_id': fields.many2one('product.class'),
      'attr_ids': fields.relate('class_id', 'attr_ids', type='one2many', relation='product.attr')
   }

Is it right?

Thank you very much,

Revision history for this message
Mohsin Yaseen (myasinr) said :
#9

hi brother

On Tue, Aug 2, 2011 at 11:11 AM, Cuong <<email address hidden>
> wrote:

> Question #166633 on OpenERP Server changed:
> https://answers.launchpad.net/openobject-server/+question/166633
>
> Cuong posted a new comment:
> Hi Ferdinand,
>
> As your suggestion, I understand as following:
> 1. create a class, called 'product.class' (product type), consists of 2
> fields
> class product_class(osv.osv):
> _columns = {
> 'name': fields.char, =>
> category name: LCD, CPU, Mainboard,...
> 'attr_ids': fields.one2many('product.attribute', 'class_id') => point
> to list of properties
> }
> class product_attr(osv.osv):
> _columns = {
> 'name': fields.char,
> 'value': fields.,
> 'class_id': fields.many2one('product.class')
> }
>

ur solution will be like below;

from osv import osv, fields

class product_class(osv.osv):
    """(NULL)"""
    _name = 'product.class'
    _columns = {
        'name': fields.char('Name', size=100),
        'attrs_ids': fields.one2many('product.attr','class_id', 'Product
Class'),
    }
product_class()

class product_attr(osv.osv):
    """(NULL)"""
    _name = 'product.attr'
    _columns = {
        'name': fields.char('Name', size=100),
        'value': fields.char('Value', size=100),
        'class_id': fields.many2one('product.class', 'Product Class'),
    }
product_attr()

>
> 2. next, in product.product, create a many2one field to product.class.
> Also, create a related field of type one2many
> class product(osv.osv):
> _columns = {
> 'class_id': fields.many2one('product.class'),
> 'attr_ids': fields.relate('class_id', 'attr_ids', type='one2many',
> relation='product.attr')
> }
>

for this u need to inherit product.product in ur module.
ur problem will be solve

>
> Is it right?
>
> Thank you very much,
>
> --
> You received this question notification because you are a member of
> OpenERP Framework Experts, which is an answer contact for OpenERP
> Server.
>

thanks

--
-----------------------------
Mohsin Yaseen
OpenERP Developer, IMSciences
Finance Manager, Meher Traders
http://www.linkedin.com/in/rmyasin
http://mohsinpage.wordpress.com
http://twitter.com/moshsin
http://www.flickr.com/photos/myasinr
Mohsin Facebook Page<http://www.facebook.com/pages/Mohsin-Page/180815835319473>
<http://www.facebook.com/pages/Mohsin-Page/180815835319473>+923349069919
(prefer)
+923129069919
<email address hidden>

Revision history for this message
Ferdinand (office-chricar) said :
#10

yes

I suggested to attach the product attributes to product categories instead of inventing a new "product class", except you need product categories REALY for something else.

product_category
 |--- product_attributes

product_product
| --- product_attribute_values

IMHO this would be a nice general module because a lot of companies might need this

Revision history for this message
Ferdinand (office-chricar) said :
#11

to make it more clear)

product_category
 |--- product_attributes (category_id, name, ... other info)

product_product
| --- product_attribute_values (product_id,attribute_id,value, other info)

Revision history for this message
Cuong (bhcuong2008) said :
#12

Hi Ferdinand,

Now, I see your point. I think your approach is the best in case of human reading, and user defined attributes, not for computing. In coding or doing sql query, we can't access these attributes. If a product has attributes such as 'color' or 'frequency', 'size',...we can't access product.color, product.size,...

But in my case, these attributes must be pre-defined, some attributes are used for computing purpose. So I must define these attributes as columns, not rows. I attach to generalization/specialization data modeling. In principle, delegation inheritance in OpenERP can solve database structure. But the view, which data is displayed to users, can't be solved.

With form view, the way Raphael suggested can solve this partially. Because data is displayed/edited by clicking on button to pop up wizard. Perfectly, data should be displayed right on product form.

With tree view/search view, we should display to users what they need. For ex, when they choose CPU type, just related columns displayed such as frequency, number of core, Intel/AMD, code name,...other columns such as panel_size, Led/CRT/LCD, should be hidden.

Besides, I'm doing on wood products, it must have dimension attribute, and it's used for area (m2), cubic(m3) calculation. Other attributes are also important for calculation.

Up to now, I'm stuck with views for users displaying/editing.

Thank you very much,

Revision history for this message
Cuong (bhcuong2008) said :
#13

Currently, I have a thought but I dont know whether it's possible or not.

For showing to users, I will make a view in database for joining all product-related tables, such as product_product, product_monitor, product_cpu, product_mainboard, product_case, product_disk,...But I dont know how to make columns visible/invisible to users depending on value of product type users choose in search view.

Thanks,

Revision history for this message
Ferdinand (office-chricar) said :
#14

if you follow my advice you will have only ONE table.

and I suggested to create a function field which reads all attributes of a product and produces a list of
[attrribute_name:value], [attrribute_name:value], .... in ONE line
this field you can use in list/tree view or for printing product lists

Revision history for this message
Raphaël Valyi - http://www.akretion.com (rvalyi) said :
#15

Hello Ferdinand, we are implementing something very generic a bit similar.
See current work for 6.1:
https://code.launchpad.net/~akretion-team/openobject-server/custom_update_field/+merge/67105

On Tue, Aug 2, 2011 at 7:01 AM, Ferdinand @ Camptocamp <
<email address hidden>> wrote:

> Question #166633 on OpenERP Server changed:
> https://answers.launchpad.net/openobject-server/+question/166633
>
> Ferdinand @ Camptocamp proposed the following answer:
> yes
>
> I suggested to attach the product attributes to product categories
> instead of inventing a new "product class", except you need product
> categories REALY for something else.
>
> product_category
> |--- product_attributes
>
> product_product
> | --- product_attribute_values
>
> IMHO this would be a nice general module because a lot of companies
> might need this
>
> --
> You received this question notification because you are a member of
> OpenERP Committers, which is an answer contact for OpenERP Server.
>

Revision history for this message
Cuong (bhcuong2008) said :
#16

Yeath,

I've just looked at the solution of Raphael. The idea of Raphael is similar to Ferdinand. The merge explains very clearly, and I will try to understand and implement it.

I wonder how can we do searching in tree view if all attributes are zipped, that represented by a function field of type text. Do we override function search on this field?

I can't wait for 6.1....

Revision history for this message
Cuong (bhcuong2008) said :
#17

Hi Ferdinand,

I also wonder how can we specify type of field 'value' if an attribute needs. For ex, if an attribute is of type datatime, integer, float, boolean, relation many2one to other objects,...In my understanding, field 'value' is of type 'text' in table you suggested, 'product_attribute_values (product_id,attribute_id,value, other info) '

Thanks,

Revision history for this message
Ferdinand (office-chricar) said :
#18

you may think of other_info as fields of specific type

then it would look like

product_category
 |--- product_attributes (category_id, name, attr_type,... other info)

product_product
| --- product_attribute_values (product_id,attribute_id,value_char,value_int,value_bool,......, other info)

but I suggest to really think of if it is necessary to store value in different fields according to their type.

if everything is stored in "value", then the python function isinstance(value,attribute_id.value) could be used to check if type entered is correct

otherwise
product_category
 |--- product_attributes (category_id, name, attr_type,... other info, python_check_code)
the field
python_check_code
could hold arbitrary python code to check the validity of what users enter

Revision history for this message
Ferdinand (office-chricar) said :
#19

btw if you need "references" - that is specific values in for the category_atrributes, you probably need reference fields as used in CRM.

Revision history for this message
Cuong (bhcuong2008) said :
#20

Hi Ferdinand,

When we use function field to join all attributes into a string, then how web client show correct type? If it's a datetime, a float then?
 Currently I try to implement your method together with Olivier's proposal in the merge.

Thank you very much.

Revision history for this message
Ferdinand (office-chricar) said :
#21

if I understood correctly the attributes should be shown in one line in one (character/text) field
something like
CPU:AMD, RAM: DDR3, MEM:4GB, ...

for search you have to provide a elaborated search view (may be dynamically generated - wizard- dependent on category)
something like (sorry German, but self explaining)
http://geizhals.at/?cat=nb

Revision history for this message
Cuong (bhcuong2008) said :
#22

Hi Ferdinand,

I means when inputting attribute value data in product form in case value is of field type of text. So we can enforce user entering correct data, also the view looks good. For example, when you enter an attribute, its type is datetime, how to use widget="datetime" to show calendar view to users.

About searching, in product tree view (view type = form), I added a button in search view to show a wizard but this button can't be displayed by openerp-web client.

So, the big issue now that I can't solve is providing a user interface for searching attributes in the same product tree view.

Thank you very much,

Revision history for this message
Ferdinand (office-chricar) said :
#23

if you really need a datetime as attribute you probalby have to create a valie_datetime field which is only enterable if the field is of datetime

About searching, - I can't help you with this,
and as I said in my first comment, it is a complex issue and for this I proposed to develop a solution for you.

Revision history for this message
Cuong (bhcuong2008) said :
#24

I agree with you. I've already implemented the method you suggested. It looks very interesting because we can add dynamically attributes. But when coming to calculation, there are many complicated things to do in codes.

Now, I'm thinking of the way to searching attributes on the tree view of product form, but seems to be stuck.

Anyway, this method is really good thing to follow. Further, serialization proposed by Raphael, fields.sparse is very useful.

If any useful information, please post it to me. I'm working on this problem. This approach, serialization, against generalization/specialization in data modeling, is really better alternative, but there are difficulties with this.

Thank you very much.

Can you help with this problem?

Provide an answer of your own, or ask Cuong for more information if necessary.

To post a message you must log in.