Skip to content

19.0 Tutorials YACHA - #1381

Draft
yacha-odoo wants to merge 11 commits into
odoo:19.0from
odoo-dev:19-tutorial-yacha
Draft

19.0 Tutorials YACHA#1381
yacha-odoo wants to merge 11 commits into
odoo:19.0from
odoo-dev:19-tutorial-yacha

Conversation

@yacha-odoo

@yacha-odoo yacha-odoo commented Aug 7, 2026

Copy link
Copy Markdown

This PR contains the implementation of the Real Estate module from the Odoo development tutorial.

It covers:

  • Creating the estate module and its models
  • Adding fields and model relationships
  • Adding security access rights
  • Creating menus, actions, and views
  • Adding property offers, types, and tags
  • Improving the property search and form views

yacha-odoo added 10 commits July 3, 2026 17:37
Create the initial Real Estate module for the Server Framework 101 tutorial.

This introduces the base module structure with the manifest and package initialization files required for further development.
Implemented Chapter 5 of the Odoo Server Framework tutorial.

- Added window action for estate.property
- Split XML into estate_property_views.xml and estate_menus.xml
- Added three-level menu hierarchy
- Added readonly and copy attributes
- Added default values for bedrooms and availability date
- Added reserved fields active and state
Introduce explicit list and form views for the estate.property model.

The autogenerated views are sufficient for basic testing but do not
provide a structured user interface. Adding custom XML views prepares
the module for subsequent tutorial chapters, where the form and list
views will be extended with notebooks, search views, widgets, and
additional UI customizations.
Add the active field to support record archiving.
Help users find properties more efficiently by providing
search shortcuts, a quick filter for available properties,
and the ability to group records by postcode.

This makes day-to-day property management faster as users
can locate relevant records without manually browsing
through the entire list.
Add the ability to classify properties by their type and keep
track of the buyer and the responsible salesperson. This makes
property records more complete, easier to manage, and prepares
the system for the complete property sales process.
Introduce property tags to classify and organize estate records
using many-to-many relationships. This improves property
categorization, enables flexible tagging of listings, and lays
the foundation for advanced search, filtering, and future
business features.
Introduce a dedicated Property Offer model to record offers
submitted by potential buyers for properties. Each offer stores
the offered price, buyer, and current offer status, and is
linked to a single property through relational fields. Display
all related offers within the property form, enabling multiple
offers to be managed from one place and preparing the estate
module for the complete property selling workflow.
@robodoo

robodoo commented Aug 7, 2026

Copy link
Copy Markdown

Pull request status dashboard

@mash-odoo mash-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.

Hello,
Good start on the task.
I have added some comments and suggestions.
Some points to be looked at:

  • Add chapter name while pushing the commits in order to understand the changes done for that particular commit.
  • Update the PR title and description according to the guidelines.
  • Reformat the necessary files.

Comment on lines +1 to +2
from odoo import api, models, fields
from dateutil.relativedelta import relativedelta

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You can refer to this for ordering your imports.

Comment on lines +5 to +7
@api.model
def _default_date_availability(self):
return fields.Date.today() + relativedelta(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.

This should be placed inside the class.
You can follow this for ordering your fields, functions, constraints etc. You can check the attribute order followed in a model.

Comment on lines +28 to +35
garden_orientation = fields.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
garden_orientation = fields.Selection(
[
("north", "North"),
("south", "South"),
("east", "East"),
("west", "West"),
]
)
garden_orientation = fields.Selection(
[
('north', "North"),
('south', "South"),
('east', "East"),
('west', "West"),
]
)

Try to keep the key i.e the technical strings in single quotes and the values which are to be displayed to the user in double quotes

Comment on lines +50 to +56
property_type_id = fields.Many2one("estate.property.type", string="Property Type")

buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)

salesperson_id = fields.Many2one(
"res.users", string="Salesperson", default=lambda self: self.env.user
)

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
property_type_id = fields.Many2one("estate.property.type", string="Property Type")
buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)
salesperson_id = fields.Many2one(
"res.users", string="Salesperson", default=lambda self: self.env.user
)
property_type_id = fields.Many2one("estate.property.type", string="Property Type")
buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)
salesperson_id = fields.Many2one(
"res.users", string="Salesperson", default=lambda self: self.env.user
)

Do not leave unnecessary lines between the field declarations.


property_type_id = fields.Many2one("estate.property.type", string="Property Type")

buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What if you do not write the string here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Odoo automatically derives the string name explicitly from the variable name. So if we don't give this string then also it is deriving string to Property Type. I tested it. So i think i should remove it.

)

partner_id = fields.Many2one("res.partner", required=True)
property_id = fields.Many2one("estate.property", required=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

What is the difference between setting a field as required=True in the model and required="1" in the XML view?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

required=True makes the field mandatory at the model level, so it applies whenever the field is used. required="1" in the XML only makes the field mandatory in that specific view.

Comment on lines +4 to +16
<menuitem
id="estate_menu_root"
name="Real Estate">

<menuitem
id="estate_advertisements_menu"
name="Advertisements">

<menuitem
id="estate_property_menu_action"
action="estate_property_action"/>

</menuitem>

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
<menuitem
id="estate_menu_root"
name="Real Estate">
<menuitem
id="estate_advertisements_menu"
name="Advertisements">
<menuitem
id="estate_property_menu_action"
action="estate_property_action"/>
</menuitem>
<menuitem
id="estate_menu_root"
name="Real Estate"
>
<menuitem
id="estate_advertisements_menu"
name="Advertisements"
>
<menuitem
id="estate_property_menu_action"
action="estate_property_action"
/>
</menuitem>

Re-format this file a bit.

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is it compulsory to write this?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

It's the XML declaration that identifies the file as an XML 1.0 document. It's the standard way to start an XML file.
If we don't write it still ODOO parses the XML files and shows no errors
But we still explicitly define the version of that xml file.


<group>
<field name="property_type_id"/>
<field name="tag_ids" widget="many2many_tags"/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Why do we use a widget?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

We use a widget when we want to change the default way a field is displayed or interacted with in the view. It allows us to provide a more suitable UI for that particular field.

Comment thread estate/__manifest__.py
{
"name": "Real Estate",
"version": "1.0",
"author": "yacha",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When you are working for a company, you should keep the author name as Odoo S.A. or just skip writing it.

@yacha-odoo yacha-odoo changed the title [ADD] module: Adding a new Module - Real Estate 19.0 Tutorials YACHA Aug 18, 2026
@yacha-odoo
yacha-odoo requested a review from mash-odoo August 18, 2026 07:16
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.

3 participants