Skip to content

mfre - Technical Training #819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Conversation

mfreym
Copy link

@mfreym mfreym commented Jun 18, 2025

No description provided.

@robodoo
Copy link

robodoo commented Jun 18, 2025

Pull request status dashboard

@mfreym mfreym force-pushed the 18.0-tutorials-mfre branch from 7d64637 to 31cdaf8 Compare June 19, 2025 12:31
Copy link

@aboo-odoo aboo-odoo left a comment

Choose a reason for hiding this comment

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

Hey! Good job for this PR, I have some comments feel free to argue 🎉

A few generic comments:

  • Could you add a description to the PR and change the PR title according to the guideline [XYZ] module: short desc. like for a commit message link
  • Usually, you'll want one commit / task to keep the chain of commits as clean and small as possible. As here, the task is to create the module Estate, it should be the one commit on your branch. Could you squash your commits into 1 ?

@@ -0,0 +1,3 @@
from . import models

from odoo import api, SUPERUSER_ID

Choose a reason for hiding this comment

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

Why is this here ? 😄

Comment on lines 2 to 12
"name": "Estate Module",
"depends": ["base"],
"data": [
"security/ir.model.access.csv",
"views/estate_property_offer_views.xml",
"views/estate_property_type_views.xml",
"views/estate_property_tag_views.xml",
"views/estate_property_views.xml",
"views/estate_menus.xml",
],
"license": "LGPL-3",

Choose a reason for hiding this comment

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

As a global comment: double quote " should be used for strings that will be displayed and single quote ' for the rest

Suggested change
"name": "Estate Module",
"depends": ["base"],
"data": [
"security/ir.model.access.csv",
"views/estate_property_offer_views.xml",
"views/estate_property_type_views.xml",
"views/estate_property_tag_views.xml",
"views/estate_property_views.xml",
"views/estate_menus.xml",
],
"license": "LGPL-3",
'name': "Estate Module",
'depends': ['base'],
'data': [
'security/ir.model.access.csv',
'views/estate_property_offer_views.xml',
'views/estate_property_type_views.xml',
'views/estate_property_tag_views.xml',
'views/estate_property_views.xml',
'views/estate_menus.xml',
],
'license': 'LGPL-3',

Comment on lines 1 to 6
from odoo import fields, models, api
from odoo.exceptions import UserError
from datetime import date
from dateutil.relativedelta import relativedelta
from odoo.tools.float_utils import float_compare, float_is_zero
from odoo.exceptions import ValidationError

Choose a reason for hiding this comment

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

The imports should be

  1. External libraries (one per line sorted and split in python stdlib)
  2. Imports of odoo
  3. Imports from Odoo modules (rarely, and only if necessary)

Inside these 3 groups, the imported lines are alphabetically sorted. You can use RUFF to help you sort them, it's quite handy

_sql_constraints = [
(
"expected_price_strictly_positive",
"CHECK(expected_price > 0)",

Choose a reason for hiding this comment

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

Same comment about the " and '


@api.constrains("expected_price", "selling_price")
def _check_selling_price(self):
for record in self:

Choose a reason for hiding this comment

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

record is a bit too generic, it's fine for small method like this. But when you'll work in huuuge methods, you'll be happy to have a name a bit more meaningful trust me

Suggested change
for record in self:
for estate in self:

date_availability = fields.Date(
string="Available From",
copy=False,
default=date.today() + relativedelta(months=3),

Choose a reason for hiding this comment

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

This default value will be computed once the server starts, if I start and let it run 3 months, then the default availability date will be today(the today 3 month ago) + 3 months = today aha

Like for the salesperson_id it should use a lambda function.

Choose a reason for hiding this comment

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

Again, the order in the file is important. Here, I was like, where is the offer status to only find it at the bottom. Keep it consistent

Comment on lines 37 to 43
record.date_deadline = record.create_date.date() + timedelta(
days=record.validity
)
else:
record.date_deadline = fields.Datetime.now().date() + timedelta(
days=record.validity
)

Choose a reason for hiding this comment

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

Suggested change
record.date_deadline = record.create_date.date() + timedelta(
days=record.validity
)
else:
record.date_deadline = fields.Datetime.now().date() + timedelta(
days=record.validity
)
record.date_deadline = (record.create_date.date() or fields.Date.now()) + timedelta(
days=record.validity
)

<menuitem id="estate_property_tag_menu" action="estate_property_tag_action" />
</menuitem>
</menuitem>
</odoo>

Choose a reason for hiding this comment

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

Try to always add a EOL in each file so that when someone adds lines in the future, the last line of the previous devs is not in the diff

@@ -0,0 +1,33 @@
<odoo>
<record id="view_estate_property_offer_tree" model="ir.ui.view">

Choose a reason for hiding this comment

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

Convention for naming views are <model_name>view<view_type>

closes odoo#764

Signed-off-by: Antoine Vandevenne (anv) <[email protected]>

[ADD] chapter n°1

[ADD] chapter n°2+n°3

[ADD] chapter n°4

[ADD] chapter n°5+n°6

[ADD] chapter n°7

[ADD] estate: Add a special mention section

task-#######

[FIX] fixed styling issues and license in the manifest

[ADD] chapter n°8

[ADD] chapter n°9+n°10

[ADD] chapter n°11 to n°15
@mfreym mfreym force-pushed the 18.0-tutorials-mfre branch from d4a6118 to aa107c0 Compare June 25, 2025 10:12
Copy link

@aboo-odoo aboo-odoo left a comment

Choose a reason for hiding this comment

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

Hey! Final review on the python part, it focuses on functionality, not style anymore 😄

By the end of the, try to get your runbot green 🟢 and fix the comments in this review please 👍

Also, there is a lot of noise in your PR (all the website_airproof stuff); it'd be nice to remove them 👍
I can help you do it if you need help :P

def action_sold(self):
for property_record in self:
if property_record.state == 'cancelled':
raise UserError("A cancelled property cannot be set as sold")

Choose a reason for hiding this comment

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

Most strings are automatically made translatable: field names, module and model names, etc. But this is not the case for error messages. To make them translatable, use the _() method like so

Suggested change
raise UserError("A cancelled property cannot be set as sold")
raise UserError(_"A cancelled property cannot be set as sold"))

This applies to all your error messages

Comment on lines +111 to +114
if property.offer_ids:
property.best_offer = max(map(lambda r: r.price, property.offer_ids))
else:
property.best_offer = None

Choose a reason for hiding this comment

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

Suggested change
if property.offer_ids:
property.best_offer = max(map(lambda r: r.price, property.offer_ids))
else:
property.best_offer = None
property.best_offer = max(property.offer_ids.mapped('price'), default=0.0)

Comment on lines +43 to +56
@api.model
def create(self, vals):
property_id = vals.get('property_id')

property = self.env['estate.property'].browse(property_id)

property.state = 'offer_received'

existing_offers = self.env['estate.property.offer'].search([('property_id', '=', property_id), ('price', '>=', vals['price'])])

if existing_offers:
raise ValidationError("The offer value must be higher than existing offers.")

return super().create(vals)

Choose a reason for hiding this comment

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

We'd prefer for your create to be done in batch for better performances. Use

Suggested change
@api.model
def create(self, vals):
property_id = vals.get('property_id')
property = self.env['estate.property'].browse(property_id)
property.state = 'offer_received'
existing_offers = self.env['estate.property.offer'].search([('property_id', '=', property_id), ('price', '>=', vals['price'])])
if existing_offers:
raise ValidationError("The offer value must be higher than existing offers.")
return super().create(vals)
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
...
return super().create(vals_list)


property.state = 'offer_received'

existing_offers = self.env['estate.property.offer'].search([('property_id', '=', property_id), ('price', '>=', vals['price'])])

Choose a reason for hiding this comment

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

A search is unnecessary since you have the property already

Suggested change
existing_offers = self.env['estate.property.offer'].search([('property_id', '=', property_id), ('price', '>=', vals['price'])])
existing_offers = property.offer_ids.filter(lambda offer: offer.price > vals['price']

@aboo-odoo
Copy link

Now that your onboarding is done, could you close the PR ? 😄

@mfreym mfreym closed this Jul 1, 2025
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