-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Conversation
7d64637
to
31cdaf8
Compare
There was a problem hiding this 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 ?
estate/__init__.py
Outdated
@@ -0,0 +1,3 @@ | |||
from . import models | |||
|
|||
from odoo import api, SUPERUSER_ID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this here ? 😄
estate/__manifest__.py
Outdated
"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", |
There was a problem hiding this comment.
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
"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', |
estate/models/estate_property.py
Outdated
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The imports should be
- External libraries (one per line sorted and split in python stdlib)
- Imports of odoo
- 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
estate/models/estate_property.py
Outdated
_sql_constraints = [ | ||
( | ||
"expected_price_strictly_positive", | ||
"CHECK(expected_price > 0)", |
There was a problem hiding this comment.
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 '
estate/models/estate_property.py
Outdated
|
||
@api.constrains("expected_price", "selling_price") | ||
def _check_selling_price(self): | ||
for record in self: |
There was a problem hiding this comment.
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
for record in self: | |
for estate in self: |
estate/models/estate_property.py
Outdated
date_availability = fields.Date( | ||
string="Available From", | ||
copy=False, | ||
default=date.today() + relativedelta(months=3), |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
record.date_deadline = record.create_date.date() + timedelta( | ||
days=record.validity | ||
) | ||
else: | ||
record.date_deadline = fields.Datetime.now().date() + timedelta( | ||
days=record.validity | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 | |
) |
estate/views/estate_menus.xml
Outdated
<menuitem id="estate_property_tag_menu" action="estate_property_tag_action" /> | ||
</menuitem> | ||
</menuitem> | ||
</odoo> |
There was a problem hiding this comment.
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"> |
There was a problem hiding this comment.
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
d4a6118
to
aa107c0
Compare
There was a problem hiding this 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") |
There was a problem hiding this comment.
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
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
if property.offer_ids: | ||
property.best_offer = max(map(lambda r: r.price, property.offer_ids)) | ||
else: | ||
property.best_offer = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) |
@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) |
There was a problem hiding this comment.
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
@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'])]) |
There was a problem hiding this comment.
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
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'] |
Now that your onboarding is done, could you close the PR ? 😄 |
No description provided.