Skip to content

Commit d5a3567

Browse files
committed
[REF] estate: Refactoring to the coding guidelines
1 parent 199b3c2 commit d5a3567

16 files changed

+145
-52
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,4 @@ venv.bak/
126126
dmypy.json
127127

128128
# Pyre type checker
129-
.pyre/
129+
.pyre/

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.languageServer": "None"
3+
}

estate/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
'name': "estate",
3-
'version': '0.1',
3+
'version': '18.0.1.0.0',
44
'depends': ['base'],
55
'data': [
66
'security/ir.model.access.csv',

estate/models/estate_property.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1-
from odoo import fields, models, api
1+
from odoo import fields, models, api, _
22
from dateutil.relativedelta import relativedelta
33
from odoo.exceptions import UserError, ValidationError
44
from odoo.tools.float_utils import float_compare, float_is_zero
55

66

77
class EstateProperty(models.Model):
8+
"""Model representing a real estate property."""
89

910
_name = "estate.property"
10-
_description = "estate properties"
11+
_description = "Real Estate Properties"
1112
_order = "id desc"
1213
_sql_constraints = [
13-
('check_expected_price', 'CHECK(expected_price > 0 )', 'expected price must be strictly positive'),
14-
('check_selling_price', 'CHECK(selling_price >= 0 )', 'selling price must be positive'),
14+
('check_expected_price', 'CHECK(expected_price > 0 )', 'Expected price must be strictly positive.'),
15+
('check_selling_price', 'CHECK(selling_price >= 0 )', 'Selling price must be positive.'),
1516
]
1617

18+
def _default_date_availability(self):
19+
return fields.Date.today() + relativedelta(months=3)
20+
1721
name = fields.Char("Title", required=True)
1822
description = fields.Text("Description")
1923
postcode = fields.Char("Postcode")
20-
date_availability = fields.Date("Available From", default=(fields.Date.today() + relativedelta(months=3)))
24+
date_availability = fields.Date("Available From", default=_default_date_availability)
2125
expected_price = fields.Float("Expected Price", required=True)
2226
selling_price = fields.Float("Selling Price", readonly=True, copy=False)
2327
bedrooms = fields.Integer("Bedrooms", default=2)
@@ -32,7 +36,7 @@ class EstateProperty(models.Model):
3236
('north', "North"),
3337
('south', "South"),
3438
('east', "East"),
35-
('west', "West")
39+
('west', "West"),
3640
],
3741
)
3842
active = fields.Boolean("Active", default=True)
@@ -79,24 +83,22 @@ def _onchange_garden(self):
7983
def action_sold(self):
8084
for record in self:
8185
if record.state == 'canceled':
82-
raise UserError("Canceled properties cannot be sold.")
83-
else:
84-
record.state = 'sold'
86+
raise UserError(_("Canceled properties cannot be sold."))
87+
record.state = 'sold'
8588

8689
def action_cancel(self):
8790
for record in self:
8891
if record.state == 'sold':
89-
raise UserError("Sold properties cannot be canceled.")
90-
else:
91-
record.state = 'canceled'
92+
raise UserError(_("Sold properties cannot be canceled."))
93+
record.state = 'canceled'
9294

9395
@api.constrains('expected_price', 'selling_price')
9496
def _check_selling_price(self):
9597
for record in self:
9698
if not float_is_zero(record.selling_price, precision_rounding=0.01) and float_compare(record.selling_price, record.expected_price * 0.9, precision_rounding=0.01) < 0:
97-
raise ValidationError("the selling price cannot be lower than 90% of the expected price")
99+
raise ValidationError(_("The selling price cannot be lower than 90% of the expected price."))
98100

99101
@api.ondelete(at_uninstall=False)
100102
def _unlink_if_state_is_new_or_cancelled(self):
101103
if any(record.state not in ('new', 'canceled') for record in self):
102-
raise UserError("Only new and canceled properties can be deleted.")
104+
raise UserError(_("Only new and canceled properties can be deleted."))

estate/models/estate_property_offer.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
from odoo import fields, models, api
1+
from odoo import fields, models, api, _
22
from dateutil.relativedelta import relativedelta
33
from odoo.exceptions import UserError
44
from odoo.tools.float_utils import float_compare
55

66

77
class EstatePropertyOffer(models.Model):
8+
"""Model representing an offer for a real estate property."""
89

910
_name = "estate.property.offer"
10-
_description = "estate property offer"
11+
_description = "Real Estate Property Offers"
1112
_order = "price desc"
1213
_sql_constraints = [
13-
('check_offer_price', 'CHECK(price > 0)', 'An offer price must be strictly positive')
14+
('check_offer_price', 'CHECK(price > 0)', 'An offer price must be strictly positive.'),
1415
]
1516

1617
price = fields.Float(string="Price")
@@ -24,7 +25,7 @@ class EstatePropertyOffer(models.Model):
2425
)
2526
partner_id = fields.Many2one("res.partner", string="Partner", required=True)
2627
property_id = fields.Many2one("estate.property", string="Property", required=True)
27-
validity = fields.Integer("Validity (days)")
28+
validity = fields.Integer("Validity (days)", default=7)
2829
deadline = fields.Date("Deadline", compute="_compute_deadline", inverse="_inverse_deadline")
2930
property_type_id = fields.Many2one(
3031
"estate.property.type", related="property_id.property_type_id", string="Property Type")
@@ -40,13 +41,12 @@ def _inverse_deadline(self):
4041

4142
def action_accept(self):
4243
if 'accepted' in self.mapped("property_id.offer_ids.status"):
43-
raise UserError("An offer is already accepted")
44-
else:
45-
for record in self:
46-
record.status = 'accepted'
47-
record.property_id.state = 'offer_accepted'
48-
record.property_id.buyer_id = record.partner_id
49-
record.property_id.selling_price = record.price
44+
raise UserError(_("An offer is already accepted."))
45+
for record in self:
46+
record.status = 'accepted'
47+
record.property_id.state = 'offer_accepted'
48+
record.property_id.buyer_id = record.partner_id
49+
record.property_id.selling_price = record.price
5050

5151
def action_refuse(self):
5252
for record in self:
@@ -60,6 +60,6 @@ def create(self, values):
6060
if prop.offer_ids:
6161
max_offer = max(prop.mapped("offer_ids.price"))
6262
if float_compare(vals["price"], max_offer, precision_rounding=0.01) <= 0:
63-
raise UserError(f"The offer must be higher than {max_offer}")
63+
raise UserError(_("The offer must be higher than %.2f."), max_offer)
6464
prop.state = "offer_received"
6565
return super().create(values)

estate/models/estate_property_tag.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33

44
class EstatePropertyTag(models.Model):
5+
"""Model representing a property tag."""
56

67
_name = "estate.property.tag"
7-
_description = "estate property tag"
8+
_description = "Real Estate Property Tag"
89
_order = "name"
910
_sql_constraints = [
10-
('unique_name', 'UNIQUE(name)', 'the tag name must be unique')
11+
('unique_name', 'UNIQUE(name)', 'The tag name must be unique.'),
1112
]
1213

1314
name = fields.Char("Name", required=True)

estate/models/estate_property_type.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33

44
class EstatePropertyType(models.Model):
5+
"""Model representing a property type."""
56

67
_name = "estate.property.type"
7-
_description = "estate property type"
8+
_description = "Real Estate Property Type"
89
_order = "name"
910
_sql_constraints = [
10-
('unique_name', 'UNIQUE(name)', 'the type name must be unique')
11+
('unique_name', 'UNIQUE(name)', 'The type name must be unique.'),
1112
]
1213

1314
name = fields.Char("Name", required=True)

estate/models/res_users.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33

44
class ResUsers(models.Model):
5+
"""Model extending users"""
56

67
_inherit = "res.users"
78

89
property_ids = fields.One2many(
9-
"estate.property", "user_id", string="Properties", domain=[("state", "in", ["new", "offer_received"])]
10+
"estate.property", "user_id", string="Properties", domain=[("state", "in", ["new", "offer_received"])],
1011
)

estate/views/estate_property_offer_views.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<field name="res_model">estate.property.offer</field>
55
<field name="view_mode">list,form</field>
66
</record>
7-
<record id="estate_property_offer_list" model="ir.ui.view">
8-
<field name="name">estate.property.offer.list</field>
7+
<record id="estate_property_offer_view_list" model="ir.ui.view">
8+
<field name="name">estate.property.offer.view.list</field>
99
<field name="model">estate.property.offer</field>
1010
<field name="arch" type="xml">
1111
<list string="Property Offers" editable="bottom" decoration-success="status == 'accepted'" decoration-danger="status == 'refused'">

estate/views/estate_property_tag_views.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<field name="res_model">estate.property.tag</field>
55
<field name="view_mode">list,form</field>
66
</record>
7-
<record id="estate_property_tag_list" model="ir.ui.view">
8-
<field name="name">estate.property.tag.list</field>
7+
<record id="estate_property_tag_view_list" model="ir.ui.view">
8+
<field name="name">estate.property.tag.view.list</field>
99
<field name="model">estate.property.tag</field>
1010
<field name="arch" type="xml">
1111
<list string="Property Tags" editable="bottom">

estate/views/estate_property_type_views.xml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<field name="res_model">estate.property.type</field>
55
<field name="view_mode">list,form</field>
66
</record>
7-
<record id="estate_property_type_form" model="ir.ui.view">
8-
<field name="name">estate.property.type.form</field>
7+
<record id="estate_property_type_view_form" model="ir.ui.view">
8+
<field name="name">estate.property.type.view.form</field>
99
<field name="model">estate.property.type</field>
1010
<field name="arch" type="xml">
1111
<form>
@@ -38,8 +38,8 @@
3838
</form>
3939
</field>
4040
</record>
41-
<record id="estate_property_type_list" model="ir.ui.view">
42-
<field name="name">estate.property.type.list</field>
41+
<record id="estate_property_type_view_list" model="ir.ui.view">
42+
<field name="name">estate.property.type.view.list</field>
4343
<field name="model">estate.property.type</field>
4444
<field name="arch" type="xml">
4545
<list string="Types">

estate/views/estate_property_views.xml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<field name="view_mode">list,form,kanban</field>
77
<field name="context">{'search_default_available': True}</field>
88
</record>
9-
<record id="estate_property_kanban" model="ir.ui.view">
10-
<field name="name">estate.property.kanban</field>
9+
<record id="estate_property_view_kanban" model="ir.ui.view">
10+
<field name="name">estate.property.view.kanban</field>
1111
<field name="model">estate.property</field>
1212
<field name="arch" type="xml">
1313
<kanban default_group_by="property_type_id" records_draggable="False">
@@ -36,8 +36,8 @@
3636
</kanban>
3737
</field>
3838
</record>
39-
<record id="estate_property_form" model="ir.ui.view">
40-
<field name="name">estate.property.form</field>
39+
<record id="estate_property_view_form" model="ir.ui.view">
40+
<field name="name">estate.property.view.form</field>
4141
<field name="model">estate.property</field>
4242
<field name="arch" type="xml">
4343
<form string="Properties">
@@ -99,8 +99,8 @@
9999
</form>
100100
</field>
101101
</record>
102-
<record id="estate_property_list" model="ir.ui.view">
103-
<field name="name">estate.property.list</field>
102+
<record id="estate_property_view_list" model="ir.ui.view">
103+
<field name="name">estate.property.view.list</field>
104104
<field name="model">estate.property</field>
105105
<field name="arch" type="xml">
106106
<list string="Properties" decoration-success="state in ('offer_received', 'offer_accepted')" decoration-muted="state == 'sold'" decoration-bf="state == 'offer_accepted'">
@@ -114,8 +114,8 @@
114114
</list>
115115
</field>
116116
</record>
117-
<record id="estate_property_search" model="ir.ui.view">
118-
<field name="name">estate.property.search</field>
117+
<record id="estate_property_view_search" model="ir.ui.view">
118+
<field name="name">estate.property.view.search</field>
119119
<field name="model">estate.property</field>
120120
<field name="arch" type="xml">
121121
<search string="Properties">

estate/views/res_users_views.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<odoo>
2-
<record id="view_users_form" model="ir.ui.view">
3-
<field name="name">res.users.form.inherit.estate</field>
2+
<record id="res_users_view_form" model="ir.ui.view">
3+
<field name="name">res.users.view.form.inherit.estate</field>
44
<field name="model">res.users</field>
55
<field name="inherit_id" ref="base.view_users_form"/>
66
<field name="arch" type="xml">

estate_account/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
'name': "estate_account",
3-
'version': '0.1',
3+
'version': '18.0.1.0.0',
44
'depends': ['estate', 'account'],
55
'author': "baje",
66
'category': 'Uncategorized',

estate_account/models/estate_property.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
class EstateProperty(models.Model):
5+
"""Extend estate property to create an invoice on sold."""
56

67
_inherit = "estate.property"
78

ruff.toml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# automatically generated file by the runbot nightly ruff checks, do not modify
2+
# for ruff version 0.11.4 (or higher)
3+
# note: 'E241', 'E272', 'E201', 'E221' are ignored on runbot in test files when formating a table like structure (more than two space)
4+
# some rules present here are not enabled on runbot (yet) but are still advised to follow when possible : ["B904", "COM812", "E741", "EM101", "I001", "RET", "RUF021", "TRY002", "UP006", "UP007"]
5+
6+
7+
target-version = "py310"
8+
9+
[lint]
10+
preview = true
11+
select = [
12+
"BLE", # flake8-blind-except
13+
"C", # flake8-comprehensions
14+
"COM", # flake8-commas
15+
"E", # pycodestyle Error
16+
"EM", # flake8-errmsg
17+
"EXE", # flake8-executable
18+
"F", # Pyflakes
19+
"FA", # flake8-future-annotations
20+
"FLY", # flynt
21+
"G", # flake8-logging-format
22+
"I", # isort
23+
"ICN", # flake8-import-conventions
24+
"INT", # flake8-gettext
25+
"ISC", # flake8-implicit-str-concat
26+
"LOG", # flake8-logging
27+
"PGH", # pygrep-hooks
28+
"PIE", # flake8-pie
29+
"PLC", # Pylint Convention
30+
"PLE", # Pylint Error
31+
"PLW", # Pylint Warning
32+
"PYI", # flake8-pyi
33+
"RET", # flake8-return
34+
"RUF", # Ruff-specific rules
35+
"SIM", # flake8-simplify
36+
"SLOT", # flake8-slots
37+
"T", # flake8-print
38+
"TC", # flake8-type-checking
39+
"TID", # flake8-tidy-imports
40+
"TRY", # tryceratops
41+
"UP", # pyupgrade
42+
"W", # pycodestyle Warning
43+
"YTT", # flake8-2020
44+
]
45+
ignore = [
46+
"C408", # unnecessary-collection-call
47+
"C420", # unnecessary-dict-comprehension-for-iterable
48+
"C901", # complex-structure
49+
"E266", # multiple-leading-hashes-for-block-comment
50+
"E501", # line-too-long
51+
"E713", # not-in-test
52+
"EM102", # f-string-in-exception
53+
"FA100", # future-rewritable-type-annotation
54+
"I001", # import sorting
55+
"PGH003", # blanket-type-ignore
56+
"PIE790", # unnecessary-placeholder
57+
"PIE808", # unnecessary-range-start
58+
"PLC2701", # import-private-name
59+
"PLW2901", # redefined-loop-name
60+
"RUF001", # ambiguous-unicode-character-string
61+
"RUF005", # collection-literal-concatenation
62+
"RUF012", # mutable-class-default
63+
"RUF100", # unused-noqa
64+
"SIM102", # collapsible-if
65+
"SIM108", # if-else-block-instead-of-if-exp
66+
"SIM117", # multiple-with-statements
67+
"TID252", # relative-imports
68+
"TRY003", # raise-vanilla-args
69+
"TRY300", # try-consider-else
70+
"TRY400", # error-instead-of-exception
71+
"UP031", # printf-string-formatting
72+
"UP038", # non-pep604-isinstance
73+
]
74+
75+
[lint.per-file-ignores]
76+
"**/__init__.py" = [
77+
"F401", # unused-import
78+
]
79+
80+
[lint.isort]
81+
# https://www.odoo.com/documentation/18.0/contributing/development/coding_guidelines.html#imports
82+
section-order = ["future", "standard-library", "third-party", "first-party", "local-folder"]
83+
known-first-party = ["odoo"]
84+
known-local-folder = ["odoo.addons"]

0 commit comments

Comments
 (0)