Skip to content

Conversation

@robal-odoo
Copy link

No description provided.

@robodoo
Copy link

robodoo commented Dec 16, 2025

Pull request status dashboard

@robal-odoo robal-odoo force-pushed the 19.0-estate-tutorial-robal branch from 924f90b to 0af92ad Compare December 16, 2025 12:59
@robal-odoo robal-odoo changed the title Estate tutorial (robal) [ADD] estate: add real estate module (framework 101 tutorial) Dec 16, 2025
@robal-odoo robal-odoo force-pushed the 19.0-estate-tutorial-robal branch from cab625c to d8993d0 Compare December 16, 2025 16:12
@robal-odoo robal-odoo marked this pull request as ready for review December 19, 2025 08:21
Copy link

@ushyme ushyme left a comment

Choose a reason for hiding this comment

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

Good work so far. I just have a few suggestions.

'name': 'Real Estate',
'description': 'Real Estate Advertising',
# 'version': '1.0',
'author': 'robal',
Copy link

Choose a reason for hiding this comment

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

Suggested change
'author': 'robal',
'author': 'Odoo S.A.',

As an Odoo employee, you are creating this module in the name of Odoo

name = fields.Char(string="Title", required=True)
description = fields.Text()
postcode = fields.Char()
date_availability = fields.Date(string="Available From", default=fields.Date.today() + relativedelta(months=3), copy=False)
Copy link

Choose a reason for hiding this comment

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

Suggested change
date_availability = fields.Date(string="Available From", default=fields.Date.today() + relativedelta(months=3), copy=False)
date_availability = fields.Date(string="Available From", default=lambda self: fields.Date.context_today(self) + relativedelta(months=3), copy=False)

date_availability's default was calculated only once at server launch. Wrapping it in a lambda fixes this by computing it dynamically for each new record. I also used fields.Date.context_today(self) for timezone correctness.

Comment on lines 71 to 73
if record.state == "sold":
error_msg = "This property has already been sold."
raise UserError(error_msg)
Copy link

Choose a reason for hiding this comment

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

Suggested change
if record.state == "sold":
error_msg = "This property has already been sold."
raise UserError(error_msg)
if record.state == "sold":
continue

In the action_ methods, it's slightly more user-friendly to silently ignore a button click if the record is already in the target state, rather than raising an error.

raise UserError(error_msg)

if record.state == "cancelled":
error_msg = "Cancelled properties cannot be sold."
Copy link

Choose a reason for hiding this comment

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

Suggested change
error_msg = "Cancelled properties cannot be sold."
error_msg = record.env._("Cancelled properties cannot be sold.")

User-facing strings in errors and constraints must be wrapped in record.env._() to be translatable.

Copy link
Author

@robal-odoo robal-odoo Dec 19, 2025

Choose a reason for hiding this comment

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

Is there a practical difference between using record.env._() and using _() imported with from odoo import _ or the one from self.env._() ?

Comment on lines 67 to 68
def _get_reference_date(offer: EstatePropertyOffer) -> date:
return fields.Date.today() if not offer.create_date else offer.create_date.date()
Copy link

Choose a reason for hiding this comment

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

I don't know if this function is really helpful here. I think the code would overall be more readable if this logic was inlined directly in the compute/inverse method.

Copy link
Author

Choose a reason for hiding this comment

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

Should I use context_today like in the other model ?

for record in self:
# Selling price is zero when no offer has been accepted
if not float_is_zero(record.selling_price, precision_digits=2) and float_compare(record.selling_price, 0.9 * record.expected_price, precision_digits=2) < 0:
raise ValidationError(_("A property's selling price cannot be lower that 90 percent of its expected price."))
Copy link

Choose a reason for hiding this comment

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

Suggested change
raise ValidationError(_("A property's selling price cannot be lower that 90 percent of its expected price."))
raise ValidationError(_("A property's selling price cannot be lower than 90 percent of its expected price."))

small typo


# Methods that trigger on changes
@api.onchange("garden")
def _compute_garden_defaults(self) -> None:
Copy link

Choose a reason for hiding this comment

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

Suggested change
def _compute_garden_defaults(self) -> None:
def _onchange_garden_defaults(self) -> None:

This is an onchange, not a compute. Should be named _onchange_garden_defaults or _onchange_garden.

Command.create({"name": percent_description, "quantity": 1, "price_unit": 0.06 * record.selling_price}),
Command.create({"name": admin_fee_description, "quantity": 1, "price_unit": 100.0}),
],
}
Copy link

Choose a reason for hiding this comment

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

Suggested change
}
}

{
"name": "Real Estate",
"description": "Real Estate Advertising",
"author": "robal",
Copy link

Choose a reason for hiding this comment

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

Suggested change
"author": "robal",
"author": "Odoo S.A.",

As an employee, you work in the name of Odoo.

.gitignore Outdated
Comment on lines 130 to 132

# VScode
.vscode/
Copy link

Choose a reason for hiding this comment

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

Suggested change
# VScode
.vscode/

This is personal configuration that shouldn't be pushed to the general codebase.

@robal-odoo robal-odoo force-pushed the 19.0-estate-tutorial-robal branch from 2fb7576 to 9dd3005 Compare December 19, 2025 12:44
Framework 101 tutorial
- add estate module
- add estate_account module for integration with invoicing
@robal-odoo robal-odoo force-pushed the 19.0-estate-tutorial-robal branch from 440b49e to 6b2e660 Compare December 19, 2025 14:12
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