1
1
from odoo import models , fields , api
2
+ from odoo .exceptions import ValidationError
2
3
from odoo .exceptions import UserError
4
+ from odoo .tools import float_is_zero , float_compare
3
5
from datetime import timedelta
4
6
7
+
5
8
class EstateProperty (models .Model ):
6
- _name = ' estate.property'
7
- _description = ' Estate Property'
9
+ _name = " estate.property"
10
+ _description = " Estate Property"
8
11
9
- name = fields .Char (string = "Name" ,required = True )
12
+ name = fields .Char (string = "Name" , required = True )
10
13
description = fields .Text (string = "Description" )
11
14
active = fields .Boolean (
12
15
string = "Active" ,
13
- default = True ,
14
- help = "Mark as active if you want the property to be listed." ,)
16
+ default = True ,
17
+ help = "Mark as active if you want the property to be listed." ,
18
+ )
15
19
postcode = fields .Char (string = "Postcode" )
16
20
property_type_id = fields .Many2one ("estate.property.type" , string = "Property Type" )
17
21
date_availability = fields .Date (
18
- string = 'Available From' ,
19
- default = fields .Date .today () + timedelta (days = 90 ),
20
- copy = False )
21
- expected_price = fields .Float (string = "Expected Price" ,required = True )
22
- selling_price = fields .Float (string = "Selling Price" ,readonly = True ,copy = False )
23
- bedrooms = fields .Integer (string = "Bedrooms" ,default = 2 )
22
+ string = "Available From" ,
23
+ default = fields .Date .today () + timedelta (days = 90 ),
24
+ copy = False ,
25
+ )
26
+ expected_price = fields .Float (string = "Expected Price" , required = True )
27
+ selling_price = fields .Float (string = "Selling Price" , readonly = True , copy = False )
28
+ bedrooms = fields .Integer (string = "Bedrooms" , default = 2 )
24
29
living_area = fields .Integer (string = "Living Area (sqm)" )
25
30
facades = fields .Integer (string = "Facades" )
26
31
garage = fields .Boolean (string = "Garage" )
27
32
garden = fields .Boolean (string = "Garden" )
28
33
garden_area = fields .Integer (string = "Garden Area (sqm)" )
29
34
garden_orientation = fields .Selection (
30
- string = ' Garden Orientation' ,
31
- selection = [
32
- (' north' , ' North' ),
33
- (' south' , ' South' ),
34
- (' east' , ' East' ),
35
- (' west' , ' West' )
35
+ string = " Garden Orientation" ,
36
+ selection = [
37
+ (" north" , " North" ),
38
+ (" south" , " South" ),
39
+ (" east" , " East" ),
40
+ (" west" , " West" ),
36
41
],
37
42
)
38
43
total_area = fields .Integer (
@@ -55,29 +60,32 @@ class EstateProperty(models.Model):
55
60
salesman_id = fields .Many2one (
56
61
"res.users" , string = "Salesman" , default = lambda self : self .env .user
57
62
)
58
- buyer_id = fields .Many2one ("res.partner" , string = "Buyer" , copy = False )
63
+ buyer_id = fields .Many2one ("res.partner" , string = "Buyer" , copy = False )
59
64
60
65
tag_ids = fields .Many2many (
61
- ' estate.property.tag' ,
62
- string = ' Tags' ,
63
- help = ' Properties associated with this tag.'
64
- )
66
+ " estate.property.tag" ,
67
+ string = " Tags" ,
68
+ help = " Properties associated with this tag." ,
69
+ )
65
70
66
71
offer_ids = fields .One2many (
67
- 'estate.property.offer' ,
68
- 'property_id' ,
69
- string = 'Offers' ,
70
- help = 'Offers made on this property.' )
71
-
72
+ "estate.property.offer" ,
73
+ "property_id" ,
74
+ string = "Offers" ,
75
+ help = "Offers made on this property." ,
76
+ )
77
+
72
78
best_price = fields .Float (
73
- string = "Best Offer" ,
74
- compute = "_compute_best_price" ,
79
+ string = "Best Offer" ,
80
+ compute = "_compute_best_price" ,
75
81
)
76
-
77
- @api .depends (' living_area' , ' garden_area' , ' garden' )
82
+
83
+ @api .depends (" living_area" , " garden_area" , " garden" )
78
84
def _compute_total_area (self ):
79
85
for property in self :
80
- property .total_area = property .living_area + (property .garden_area if property .garden else 0 )
86
+ property .total_area = property .living_area + (
87
+ property .garden_area if property .garden else 0
88
+ )
81
89
82
90
@api .depends ("offer_ids.price" )
83
91
def _compute_best_price (self ):
@@ -89,27 +97,55 @@ def _onchange_garden(self):
89
97
for property in self :
90
98
if property .garden :
91
99
property .garden_area = 10
92
- property .garden_orientation = ' north'
100
+ property .garden_orientation = " north"
93
101
else :
94
102
property .garden_area = 0
95
103
property .garden_orientation = False
96
104
97
105
def action_set_sold (self ):
98
106
for property in self :
99
107
if property .selling_price > 0.0 and property .state != "cancelled" :
100
- property .state = ' sold'
108
+ property .state = " sold"
101
109
elif property .state == "cancelled" :
102
110
raise UserError ("A cancelled property cannot be sold." )
103
111
elif property .state == "new" or property .state == "offer received" :
104
- raise UserError ("This property must have an accepted offer before it can be sold." )
112
+ raise UserError (
113
+ "This property must have an accepted offer before it can be sold."
114
+ )
105
115
elif property .state == "sold" :
106
116
raise UserError ("This property is already sold." )
107
-
117
+
108
118
def action_set_cancelled (self ):
109
119
for property in self :
110
120
if property .state != "cancelled" and property .state != "sold" :
111
- property .state = ' cancelled'
121
+ property .state = " cancelled"
112
122
elif property .state == "cancelled" :
113
123
raise UserError ("This property is already cancelled." )
114
124
elif property .state == "sold" :
115
- raise UserError ("A sold property cannot be cancelled." )
125
+ raise UserError ("A sold property cannot be cancelled." )
126
+
127
+ _sql_constraints = [
128
+ (
129
+ "check_expected_price" ,
130
+ "CHECK(expected_price > 0)" ,
131
+ "The expected price must be greater than 0." ,
132
+ ),
133
+ ]
134
+
135
+ @api .constrains ("selling_price" , "expected_price" )
136
+ def _check_selling_price (self ):
137
+ for property in self :
138
+ if float_is_zero (property .selling_price , precision_rounding = 2 ):
139
+ continue
140
+
141
+ if (
142
+ float_compare (
143
+ property .selling_price ,
144
+ property .expected_price * 0.9 ,
145
+ precision_rounding = 2 ,
146
+ )
147
+ < 0
148
+ ):
149
+ raise ValidationError (
150
+ "The selling price cannot be lower than 90'%' of the expected price!"
151
+ )
0 commit comments