Skip to content

[ADD] : Creation of the new module - #1412

Open
macai-odoo wants to merge 15 commits into
odoo:19.0from
odoo-dev:19.0-training-tutorial-macai
Open

macai-odoo wants to merge 15 commits into
odoo:19.0from
odoo-dev:19.0-training-tutorial-macai

Conversation

@macai-odoo

Copy link
Copy Markdown

Module creation as requested in the tutorial

Module creation as requested in the tutorial
@robodoo

robodoo commented Sep 15, 2026

Copy link
Copy Markdown

Pull request status dashboard

Relate to chapter 3 of the tutorial
Relate to chapter 4 of the tutorial

@msho-odoo msho-odoo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work 🔥

For the commit message we write in a way that aligns with when this commit is merged it will ..... and we add the name of the modules before the column :
so you might change it to something like [IMP] estate: add estate property model or however you like to describe your changes :)
refer to Git Guidlines
Also, left you some comments, thanks!

Comment thread estate/models/__init__.py Outdated
@@ -0,0 +1 @@
from . import estate_property No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always add a new line for end of files :)

Comment on lines +19 to +22
garden_orientation = fields.Selection(
string='Garden Orientation',
selection=[('North','North'),('South','South'),('East','East'),('West','West')]
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The one line on the selection field is okay but when you have many values, it's better to have it like this.
Also, it's preferable to have the key as all small letters, so no confusion happens when they are used inside the code in if statements for example.

nitpick: some teams might stick to single quotes being only on technical strings (the ones that the user don't see) and double quotes are for the strings that the user can see)
so for example the selection can be ('east', "East") instead of ('east', 'East') but some teams don't do this, they just stick to their own convention which is all single quotes (if possible) or all double quotes
But I see you have all single quotes so good for me but thought to mention it so you know.

Suggested change
garden_orientation = fields.Selection(
string='Garden Orientation',
selection=[('North','North'),('South','South'),('East','East'),('West','West')]
)
garden_orientation = fields.Selection(
string='Garden Orientation',
selection=[
('north', 'North'),
('south', 'South'),
('east', 'East'),
('west', 'West')
]
)

Comment thread estate/security/ir.model.access.csv Outdated
@@ -0,0 +1,2 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_estate,estate,model_estate_property,base.group_user,1,1,1,1 No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EOF new line please for all files :)
Also alwyas refer to your runbot ci/style, if it's red, it will be telling you in the logs what's to fix :)

Comment thread estate/security/ir.model.access.csv Outdated
@@ -0,0 +1,2 @@
id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
access_estate,estate,model_estate_property,base.group_user,1,1,1,1 No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to have it like this

Suggested change
access_estate,estate,model_estate_property,base.group_user,1,1,1,1
access_estate_property_user,access.estate.property,model_estate_property,base.group_user,1,1,1,1

The access_ thing is just a convention for this and I added _user at the end because this access rule is for the base user, you might have other rules on the same model but for _manager for example and son on.

Comment thread estate/__manifest__.py Outdated
'name':'Real Estate',
'version':'1.0',
'depends':['base'],
'data':['security/ir.model.access.csv']

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'data':['security/ir.model.access.csv']
'data': [
'security/ir.model.access.csv',
]

there is also a space after each column : :)

As mentioned in the chapter 5 of the training
Corrected the code based on the feedback from the PR (Thank you !)
@msho-odoo

Copy link
Copy Markdown

@macai-odoo please mention me here when you think the PR is ready for another review so I know, typically, after each chapter :)

Feature based on chapter 6 of the training
Feature based on chapter 6 of the training
@macai-odoo

Copy link
Copy Markdown
Author

Hello !
@msho-odoo I just finished the chapter 6 of the training !

Thank you !

Feature based on chapter 7 of the training
@macai-odoo

Copy link
Copy Markdown
Author

This is the chapter 7 of the training with the implementation of :

  • Property Type
  • Property Tags
  • Property Offers

@msho-odoo msho-odoo left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the nice work and for the green ci/style on runbot :)
Have a look a the warning in ci/tutorials and see how to get rid of them, it's stated in the logs there.

Left you some comments :)
Remember to ping again when ready for review, Thanks!

Comment thread estate/models/estate_property.py Outdated
name = fields.Char('Name', required=True)
description = fields.Text('Description')
postcode = fields.Char('Postcode', required=True)
date_availability = fields.Date('Availability', copy=False, default=fields.Date.add(fields.Date.today(), months=3))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the default in this case the date will be valuated when first imported only, you need to call a function for the default here, check lambda on the code base and see how it's used in the default of the fields and use it here :)

Comment thread estate/models/estate_property.py Outdated
Comment on lines +22 to +25
selection=[('north', 'North'),
('south', 'South'),
('east', 'East'),
('west', 'West')]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
selection=[('north', 'North'),
('south', 'South'),
('east', 'East'),
('west', 'West')]
selection=[
('north', 'North'),
('south', 'South'),
('east', 'East'),
('west', 'West'),
]

Comment thread estate/models/estate_property.py Outdated
Comment on lines +30 to +34
selection=[('new', 'New'),
('offer_received', 'Offer Received'),
('offer_accepted', 'Offer accepted'),
('sold', 'Sold'),
('cancelled', 'Cancelled')],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same styling as previous selection field :)

Comment thread estate/views/estate_menu.xml Outdated
<?xml version="1.0"?>
<odoo>
<menuitem id="test_menu_root" name="Real Estate">
<menuitem id="test_first_level_menu" name="Advertisements">

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ids should be a bit more descriptive than that so other developers know mostly what it does from the name :)

Comment thread estate/views/estate_property_views.xml Outdated
Comment on lines +51 to +59
<group>
<field name="description" string="Description"/>
</group>
<group>
<field name="bedrooms" string="Bedrooms"/>
</group>
<group>
<field name="living_area" string="Living Area (sqm)"/>
</group>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm I think you don't need to add each field to a <group> tag, you do this to style different groups of fields that you want to show together, feel free to have a look at one of odoo's existing form view in any app and have a look at it's form xml record to see it better.

<field name="living_area" string="Living Area (sqm)"/>
</group>
<group>
<field name="facades" string="Facades"/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's totally correct to have string attribute on the field in the xml view but you can have it on the field definition on the python model and don't use it here so you don't have to add the string attribute every time you use it in a view (unless you want to show it differently in certain views)

Comment thread estate/models/estate_property.py Outdated
bedrooms = fields.Integer('Bedrooms', default=2)
living_area = fields.Integer('Living Area')
facades = fields.Integer('Facades')
garage = fields.Boolean('Garage')

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's better practice to have boolean fields as is_something or has_something, so you may rename the fields to has_garden and has_garage

Comment thread estate/views/estate_property_views.xml Outdated
Comment on lines +95 to +96
<filter string="Available" name="active" domain="['|', ('state', '=', 'new'),
('state', '=', 'offer_received')]"/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stick to the correct convention you were following name attribute before string attribute :)
Also, the domain like this is more readable (yours is still correct)

Suggested change
<filter string="Available" name="active" domain="['|', ('state', '=', 'new'),
('state', '=', 'offer_received')]"/>
<filter name="active" string="Available" domain="[('state', 'in', ('new', 'offer_received'))]"/>

Comment thread estate/__manifest__.py Outdated
Comment on lines +7 to +11
'data': [
'security/ir.model.access.csv',
'views/estate_property_views.xml',
'views/estate_menu.xml',
]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'data': [
'security/ir.model.access.csv',
'views/estate_property_views.xml',
'views/estate_menu.xml',
]
'data': [
'security/ir.model.access.csv',
'views/estate_property_views.xml',
'views/estate_menu.xml',
]

Change style
Change filter to match convention (estate_property_views.xml)
rename boolean variable
remove <group> block around each <field> for (estate_property_views.xml)
change id for menuitem (estate_menu.xml)
added lamba for the default for date_availability
added author & license key in manifest
As refer in the chapter 8 of the training
As refer in the chapter 8 of the training
@macai-odoo

macai-odoo commented Sep 17, 2026

Copy link
Copy Markdown
Author

@msho-odoo Hello !
I've completed the chapter 8, thank you in advance for your feedback !

I also have a small question regarding the compute field.
In most of the exemple, they used a for each loop on self, is it mandatory to do so ?
(Got the answer in chapter 9 :) )
Thanks !

Remove unused import
Move the comment at the end of lines
Added buttons to cancel or 'sell' a property
Added buttons to refuse or accept an offer
Set the buyer and the price on acceptance
Refer to chapter 9 of the training
Added constraint on prices for property
Added constraint on price for property_offer
Refer to chapter 10 of the training
@aboo-odoo
aboo-odoo self-requested a review September 17, 2026 12:49
@aboo-odoo

Copy link
Copy Markdown

Hey I'll be managing your review now to spread the load among the 4 of us 😄

I also have a small question regarding the compute field. In most of the exemple, they used a for each loop on self, is it mandatory to do so ?

Glad you got the answer 👍 Indeed, self is a recordset, i.e. a group of one or more records (several estate properties for example). Due to ORM optimizations, we try to manage recordset as much as possible instead of managing individual records independently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants