If my model inherits from res.partner will its data be visible in modules that use res.partner, such as CRM - odoo

I have a custom model mymodule.contacts which inherits from res.partner because I new a few extra fields. I would like my records that I add to mymodule.contacts to be visible in the other Odoo modules, sans my extra fields .. i.e. the fields in my model which inherit from res.partner are the only ones that possibly could be visible in the other Odoo models and that's fine. so for example, the Invoice module uses the res.partner model. My model inherits from res.partner. However since Odoo should create my model as a new table in Postgres, I dont think any of my contact data in my custom model will be visible to the Invoices module, despite inheriting from res.partner, because the actual data is in a different Postgres table. Are my assumptions correct?

It really depends on the kind of inheritance you're doing. If you do a simple inheritance with
_inherit = res.partner
To add new fields to the res.partner model, then Yes the new fields would be available to any model that has links to res.partner
On the other hand if you do a polymorphic inheritance with
_inherits = res.partner
Or you specify a _name while inheriting, A new table would be created in postgres with the attributes of the old model and your new fields won't be available to other models that inherit res.partner.
I think what you're really looking for is _inherits, it creates a new table for you. The default data for res.partner would still be stored in it's table but the new data would be stored in the new table you specified, so other models would never get to know of the new fields you added.
There is a great visualization here on the types of inheritance in Odoo.
https://www.odoo.com/forum/how-to/developers-13/whats-the-difference-between-inherit-and-inherits-52205

When you inherit a model, you simply gain its characteristics so that you can build on it. The inherited model or any other model will not have any visibility to your model unless its connected. The extra fields you add to your extension model will not be visible to any other model unless you connect them with many2one ,one2many or many2many fields.

Related

Copy standard Odoo module to new custom module

Is there a straight forward process to copy a module to a new module name with its own dependencies?
In my example I need to create a module very similar to the EVENTS module, but I also need the EVENTS module in its original form.
I figure the easiest way is to copy the events module to a new module name and then make my changes to it.
yes, you can do that... but you have to refactor the MODULE name, MODELS name, VIEWS(form,tree,action) name DIFFERENT from EVENT modules. So ur EVENT modules didn't get pile up.
Don't do that, it's a very bad idea.
Inheritance is what you want
What you want to do is create a new module with the module event as a dependency of your module. Then you can create new views that inherit existing views using the this in the view definitions:
<field name="inherit_id" ref="xml_id_of_view" />
Then all the model class that you need to update have to inherit the existing models as explained in ORM Inheritance. You'll have choice between 3 ways on inheritance:
creating a new model from an existing one, adding new information to the copy but leaving the original module as-is
extending models defined in other modules in-place, replacing the previous version
delegating some of the model’s fields to records it contains
# 1.
class Event(models.Model):
_name = "new_event"
_inherit = "event.event"
# 2.
class Event(models.Model):
_inherit = "event.event"
# 3.
class Holiday(models.Model):
_name = "event.holiday"
_inherits = {
"event.event": "event_id"
}
event_id = fields.Many2one("event.event")
I won't go into details on the 3 possible ways on inheritance to keep it short but.
Will copy the model definition to a new model so you essentially have the same thing as if you copied the code including extensions from other dependencies loaded before inheriting the model.
Will just extend the model adding new functions, will essentially share data but can be avoided by adding a type and correctly filtering models. For example you'd want a type on events to keep them separated logically while keeping them in the same table. This has the advantage to keep things together. So if you want to display multiple types of events in a calendar it will be possible.
This will create a new table having some of the data kept in a different table and new data inside the new model table. In other words when you create this new model, you'll create this model and the one being delegated. One example is having an Event and having an Holiday. The holiday type would remain in its table and you could list all holidays, but each holiday would be link to an event with a date and so on. It's a bit like inheritance method 2 with a type except that data is being isolated in different tables. For example, the holidays will be visible inside the calendar event.event but won't display anything defined in event.holiday as event.event has no idea what's an event.holiday. (for example, res.users -> res.partner is using this method).
With that said, method 2 doesn't really have any cost to implement in speed, method 1 will also be fast as data is kept in its own table but if a module extend the model and isn't in your dependency tree, the changes made to the model won't be visible so it's not 100% copying the schema.
Method 3 is good when you want to keep data normalized where each table own the data it needs to exist and the whole data of the model can be spanned across multiple tables with an implicit one2one relationship.
Also inheritance of views
Also, you can inherit views to create a new views by setting primary=True.
Documentation on views
View matching
if a view is requested by (model, type), the view with the right model and type, mode=primary and the lowest priority is matched
when a view is requested by id, if its mode is not primary its closest parent with mode primary is matched
Setting a view as primary essentially tell odoo to consider it as a top view so it doesn't extend the view it inherits but create a new view with the extension. This can be used with new models being created to prevent custom changes to affect the views of models that don't have the extension.
You can change the model of the view to handle a different model. For example, the holiday model could be handled by inheriting the event.event view and setting the model as event.holiday and changing the type of the view to primary=True. Any other module extending this new view will not have any effect on the parent event.event views.
Why not copying a whole module:
Now as to why copying an existing module is a bad idea. When you copy a module, you're taking the maintenance of the code on yourself. So any changes from one version to an other or bug fixed in the event module will not be present in your module unless you manually maintain change of code in the event module into your one.
Then you may think it's fine and can get away with it but the moment you'll want to upgrade from let say odoo12 to odoo13. Your module will have to be ported and if you want to rollback your change to create a module that extends the event module like explained above. You'll have to remember exactly which commit you forked the module from. Otherwise you'll have a hard time making a diff and seeing what changes you did introduce and how to port it to odoo13. If you only create a module that extends events, you'll have to port your changes and if you're lucky, you won't have to change anything as since odoo8-10 things didn't change much in some modules so moving from one to an other version is usually straight forward but if you copy you're adding a lot of work in the future for nothing.
Also, this is all based on personal experience after I had to work on projects and modules developed from outsourced companies. Some of the people "developing" the modules did exactly what you're trying to achieve and it costed us so much time to extract the changes made by this company to the PointOfSale which resulted in a module with a few lines of code. The module prevented us from installing the actual point of sale, and the module I had to fix was based from a very old version of the PoS missing critical bug fixes.
It simply isn't worth it.

When to use the subclass in RDFS?

I want to create a RDFS schema about venue info which contains for example:
only photo and address info.
I find another schema about it: https://schema.org/Place. It contains more properties than I need.
So, should I make my schema venue as a subclass of https://schema.org/Place?
Or I just make a new class but reuse the properties in https://schema.org/Place?
Do they have differences?
The semantic web / linked data lives of the re-use of existing vocabularies, so if you only need a sub-set of existing vocabularies, it's best to not re-invent any new schema, but just to use parts from existing ones. Your data will then even be useful without any reasoning.
Also, just cause you're using an existing vocabulary doesn't mean you need to use all of its properties or classes. Just leave those away that you're not interested in / can't provide.
So, should I make my schema venue as a subclass of https://schema.org/Place? Or I just make a new class but reuse the properties in https://schema.org/Place?
So by the above i'd recommend not to create a new class at all, but just use https://schema.org/Place.
Do they have differences?
Yes, from a reasoning & verification standpoint they do. Properties can have more or less specific domains and ranges. If you create a new class and the domain of the property you want to use is not a super-class of your new class, it would be a mistake to use that property on instances of your class. As an example look at https://schema.org/address, it can be used with instances of type https://schema.org/Organization, https://schema.org/Person and https://schema.org/Place. If you create a class that is not a subclass of one of them you shouldn't use https://schema.org/address on any of its instances.

Get all relationships of a record

If I have an Eloquent model defined in my application which has a number of different relationships set up with other model types, how can I get information all of those relationships without knowing anything else about the model I'm dealing with?
For example, imagine a simple Transaction model which can have many Lines and also belong to a single User.
Now, given an instance of the Transaction model (either populated or unpopulated), how can I find out about the relationships it has to the other models?
Just to be clear, I don't want to retrieve the actual related data, I just want to find out what class each relationship refers to and whether it is one to many, many to many etc.
Any advice appreciated.
Thanks
Laravel's eloquent models do not work this way, relationships are defined by methods within the model and are not automagically loaded by the model upon instantiation, hence the requirement to actually call these methods when you want to use a specific relationship.
When you instantiate a models class it has zero relationships defined. This can be shown by the following:
$user = new User();
print_r($user->getRelations());
//Output : empty array
As you can see the model is blissfully unaware of any relationships it may or may not have declared in relationship methods. When you call a models relationship:
$user = new User();
$user->find(1)->roles()->get();
Eloquent sets the relationship on the model using a method setRelation($relation, $value) that takes the name of the method called as the first argument and the return of that method as the second. Thus providing the context for the relationship that does not exist before you specifically ask for it.
I know this is not what you're hoping to hear but there is no way to do this with Eloquent.

Updating the existing model with Model Generator

I generate model with Model Generator and then (afterward) add a new table and new foreign keys relations.
Is it possible to update the existing model with model generator?
Or do I need to edit the code manually when I add a new table?
Have a look at the gii-template-collection and it's FullModel template.
It generates by default two classes for your models, BaseModel and Model. Best-practice for me is to add my custom functions, behaviors, scopes, etc... to Model and leave BaseModel untouched.
If you have changes in your database schema, just re-generate the BaseModel class.
No you can't edit the existing model with Gii tool. You will have to either manually update the model or generate a new one.

yii and non database models

I need some help as I seem not to be able to grasp the concept.
In a framework, namely Yii, we create models that correspond to database tables. We extend them from CActiveRecord.
However, if I want to create a class that will get some data from other models but then will do all the computations based on those results and do something with them... then how do I proceed?
I want to clearly divide the responsibility so I don't want put all the calculations in source db based models. Basically the idea is that it will be taking some stuff from some models and then updating another models with the results of the calculations.
What do I do?
Keep all the calculations in some controller and use required models? (Hesitant about this because there is a rule to keep controller slim)
Create a none db model and then work from there (how?)?
Do something else (what?)?
Thanks for any help!
For you to use the Yii interpretation of Model, you will have to create class, which depends on CModel. It is an abstract class, thus you will be required to implement attributeNames() method.
To use other "Models" with this new structure, you will need to inject them in constructor, or right after your custom model has been created.
In real MVC model is a layer, which mostly contains two sets of classes with specific responsibilities: domain business logic and data access operations. Objects which are responsible for Domain Business Logic have no clue where the information is stored and where it comes from. Or even if there is such a thing as "database".
This video might explain a bit: https://vimeo.com/21173483