-
Notifications
You must be signed in to change notification settings - Fork 2k
[ADD] estate: Added a new module named estate #733
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
base: 18.0
Are you sure you want to change the base?
Conversation
a35abec
to
329a381
Compare
'installable': True, | ||
'application': True, | ||
'auto_install': False | ||
} |
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.
Don't forget the license
key to avoid warnings in the log.
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.
Done.
@msho-odoo For the title of the commit, be aware that the commit message header should make a valid sentence once concatenated with if applied, this commit will
|
estate/__manifest__.py
Outdated
'data': [ | ||
'security/ir.model.access.csv', | ||
'views/estate_property_views.xml', | ||
'views/estate_menu.xml', | ||
], |
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.
'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', | |
], |
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_property, access_estate_property,model_estate_property,base.group_user,1,1,1,1 |
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.
EOF 👍
estate/views/estate_menu.xml
Outdated
<menuitem id="estate_property_action_menu" action="estate_property_action"></menuitem> | ||
</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.
Same here
<field name="res_model">estate.property</field> | ||
<field name="view_mode">list,form</field> | ||
</record> | ||
</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.
Same here
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.
@SergeBayet Noted.
I fixed linting and EOF problems
6f5effe
to
450100a
Compare
estate/models/estate_property.py
Outdated
@@ -10,7 +10,7 @@ class EstateProperty(models.Model): | |||
description = fields.Text('description') | |||
postcode = fields.Char('postcode') | |||
date_availability = fields.Date( | |||
'availabilty date', copy=False, default=fields.Date.today()+relativedelta(months=3)) | |||
'availabilty date', copy=False, default=fields.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.
For this diff you could use git commit --amend
to correct the previous commit :)
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.
@SergeBayet
yes, I wasn't used to using it in that sense but sure it makes sense.
Thank you for pointing these things out, it helps :)
estate/models/estate_property.py
Outdated
@@ -37,3 +37,5 @@ class EstateProperty(models.Model): | |||
"res.users", string="Salesperson", default=lambda self: self.env.user) | |||
buyer_id = fields.Many2one("res.partner", string="Buyer", copy=False) | |||
tag_ids = fields.Many2many("estate.property.tag", string="Tags") | |||
offer_ids = fields.One2many( | |||
"estate.property.offer", "property_id", string="Offers") |
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.
Silly little remark, but choose if you want to use double quotes or single quotes and stick to it :) In Python, this kind of convention depends of the team you'll be in.
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.
Some remarks :)
estate/models/estate_property.py
Outdated
|
||
@api.depends("offer_ids") | ||
def _compute_best_offer(self): | ||
try: |
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 this try/except block? What could happen?
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.
It was giving me some error but I fixed it later, removing it
estate/models/estate_property.py
Outdated
if len(record.offer_ids) > 0: | ||
record.best_offer = max(record.offer_ids.mapped("price")) | ||
else: | ||
record.best_offer = 0.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.
A more pyhtonic way:
for prop in self:
prop.best_price = max(prop.offer_ids.mapped("price")) if prop.offer_ids else 0.0
date_deadline = fields.Date( | ||
compute="_compute_date_deadline", inverse="_inverse_date_deadline") | ||
|
||
@api.depends("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.
It depends of create_date
too, isn't it?
for record in self: | ||
start_date = fields.Date.today() | ||
if record.create_date: | ||
start_date = record.create_date |
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.
Be aware that record.create_date
is a DateTime field. You can extract the date with the method date()
So maybe this could be better:
for offer in self:
date = offer.create_date.date() if offer.create_date else fields.Date.today()
offer.date_deadline = date + relativedelta(days=offer.validity)
for record in self: | ||
start_date = fields.Date.today() | ||
if record.create_date: | ||
start_date = record.create_date |
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 than above.
|
||
def _inverse_date_deadline(self): | ||
for record in self: | ||
start_date = fields.Date.today() |
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.
start_date
is never used...
eec66c2
to
658e49e
Compare
@vava-odoo You can take over this one. :) Thanks |
@SergeBayet I don't review red runbot PRs 😇 |
658e49e
to
fc150fb
Compare
@vava-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.
A few comments passing by. Good luck with next chapters 💪
estate/__manifest__.py
Outdated
], | ||
'installable': True, | ||
'application': True, | ||
'auto_install': False, |
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.
Default value are not needed (in community, this would raise a warning in runbot)
'auto_install': False, |
@@ -0,0 +1,81 @@ | |||
from odoo import api, fields, models | |||
from odoo.exceptions import UserError | |||
from dateutil.relativedelta import relativedelta |
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.
Guideline: external import first
estate/models/estate_property.py
Outdated
|
||
class EstateProperty(models.Model): | ||
_name = "estate.property" | ||
_description = "Estate Property discription" |
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.
discription 👀
estate/models/estate_property.py
Outdated
selection=[('north', 'North'), ('south', 'South'), | ||
('east', 'East'), ('west', 'West')] |
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.
usually we indent a bit differently
selection=[('north', 'North'), ('south', 'South'), | |
('east', 'East'), ('west', 'West')] | |
selection=[ | |
('north', 'North'), | |
('south', 'South'), | |
('east', 'East'), | |
('west', 'West'), | |
], |
estate/models/estate_property.py
Outdated
property_type_id = fields.Many2one( | ||
"estate.property.type", string="property type") |
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 avoid long lines, but don't be extreme. Here a one-liner is fine
property_type_id = fields.Many2one( | |
"estate.property.type", string="property type") | |
property_type_id = fields.Many2one("estate.property.type", string="property type") |
estate/models/estate_property.py
Outdated
record.best_offer = max(record.offer_ids.mapped( | ||
"price")) if record.offer_ids else 0.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.
Could use default
kwarg
record.best_offer = max(record.offer_ids.mapped( | |
"price")) if record.offer_ids else 0.0 | |
record.best_offer = max(record.offer_ids.mapped("price"), default=0.0) |
|
||
@api.onchange("garden") | ||
def _onchange_garden(self): | ||
if self.garden: |
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.
I'd say has_garden is a clearer name, but that is debatable
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.
agree, just for the sake of the tutorial
estate/models/estate_property.py
Outdated
for record in self: | ||
if record.state == "cancelled": | ||
raise UserError("You can't sell a cancelled property") | ||
record.state = "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.
Better to raise first and assign in batch. For example:
for record in self: | |
if record.state == "cancelled": | |
raise UserError("You can't sell a cancelled property") | |
record.state = "sold" | |
if "cancelled" in record.mapped('state'): | |
raise UserError("You can't sell a cancelled property") | |
self.state = "sold" |
<field name="name">properties.view.type.form</field> | ||
<field name="model">estate.property.type</field> | ||
<field name="arch" type="xml"> | ||
<form string="properties type from"> |
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.
typo
<form string="properties type from"> | |
<form string="properties type form"> |
Do you need to define this view? I think a default one is automatically created, and not quite different
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.
yes you're right.
I was following the tutorial in case I would add something later to the view, so I did it
<field name="expected_price"/> | ||
<field name="selling_price"/> | ||
<field name="availability_date"/> | ||
<filter string="Available" name="state" domain="['|',('state','=','new'),('state','=','offer_received')]"/> |
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.
Simpler:
<filter string="Available" name="state" domain="['|',('state','=','new'),('state','=','offer_received')]"/> | |
<filter string="Available" name="state" domain="[('state', 'in', ['new', 'offer_received'])]"/> |
c011c65
to
8ebd0af
Compare
8ebd0af
to
a3d2623
Compare
a3d2623
to
57d42f0
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.
Few comments passing by your PR 🙂
@api.model | ||
def create(self, vals): | ||
property_record = self.env["estate.property"].browse(vals["property_id"]) | ||
if vals["price"] < property_record.best_offer: |
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.
Pay attention that price
is not required, you need to handle cases where it is not defined
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.
@vava-odoo
I made a sql constraint on the price so it can't be left empty or 0
@api.model | ||
def create(self, 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 tend to prefer recordset over single records in odoo, could you try to adapt this to support multiple-records creation?
estate/models/estate_property_tag.py
Outdated
_name = "estate.property.tag" | ||
_description = "Estate property tag" | ||
_sql_constraints = [ | ||
("check_unique_name", "UNIQUE(name)", "Property tag must be unqie") |
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.
unqie 👀
<header> | ||
<button name="action_sell" type="object" string="Mark as Sold" invisible="state in ['sold', 'cancelled']"/> | ||
<button name="action_cancel" type="object" string="Cancel" invisible="state in ['sold', 'cancelled']"/> | ||
<field name="state" widget="statusbar" statusbar_visible="new,offer_received,offer_accepted,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.
is statusbar_visible necessary when you use all values of the selection field?
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.
@vava-odoo
There is also "cancelled", but the request was to show only those states
estate_account/__manifest__.py
Outdated
'name': 'Estate Account', | ||
'depends': | ||
['estate', 'account'], | ||
'data': [], |
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.
no need 🤷
'data': [], |
estate_account/__manifest__.py
Outdated
'installable': True, | ||
'application': True, |
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.
Ok, but would be nice to have it installed as soon as dependency modules are
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.
@vava-odoo
makes sense.
Great comments 👍
No description provided.