1
1
from dateutil .relativedelta import relativedelta
2
- from odoo import models ,fields ,api ,_
3
- from odoo .tools .float_utils import float_compare ,float_is_zero
4
- from odoo .exceptions import UserError ,ValidationError
2
+ from odoo import models , fields , api , _
3
+ from odoo .tools .float_utils import float_compare , float_is_zero
4
+ from odoo .exceptions import UserError , ValidationError
5
5
6
- class EstateProperty (models .Model ):
7
- _name = 'estate.property'
8
- _description = 'Real Estate Property'
9
- _order = 'id desc'
10
6
7
+ class EstateProperty (models .Model ):
8
+ _name = "estate.property"
9
+ _description = "Real Estate Property"
10
+ _order = "id desc"
11
11
12
- _check_expected_price = models .Constraint ('CHECK(expected_price > 0)' ,'The expected price must be positive.' )
13
- _check_selling_price = models .Constraint ('CHECK(selling_price >= 0)' ,'The selling price must be positive.' )
12
+ _sql_constraints = [
13
+ (
14
+ "_check_expected_price" ,
15
+ "CHECK(expected_price > 0)" ,
16
+ "The expected price must be positive." ,
17
+ ),
18
+ (
19
+ "_check_selling_price" ,
20
+ "CHECK(selling_price >= 0)" ,
21
+ "The selling price must be positive." ,
22
+ ),
23
+ ]
14
24
15
- name = fields .Char (required = True ,string = "Title" )
25
+ name = fields .Char (required = True , string = "Title" )
16
26
description = fields .Text ()
17
27
postcode = fields .Char ()
18
28
date_availability = fields .Date (
19
- default = lambda self : fields .Date .today () + relativedelta (months = 3 ),
20
- copy = False ,string = "Available From" )
29
+ default = lambda self : fields .Date .today () + relativedelta (months = 3 ),
30
+ copy = False ,
31
+ string = "Available From" ,
32
+ )
21
33
expected_price = fields .Float (required = True )
22
- selling_price = fields .Float (readonly = True ,copy = False )
34
+ selling_price = fields .Float (readonly = True , copy = False )
23
35
bedrooms = fields .Integer (default = 2 )
24
36
living_area = fields .Integer (string = "Living Area (sqm)" )
25
- total_area = fields .Float (compute = ' _compute_total_area' , store = True )
37
+ total_area = fields .Float (compute = " _compute_total_area" , store = True )
26
38
facades = fields .Integer ()
27
- garage = fields .Boolean ()
39
+ garage = fields .Boolean ()
28
40
garden = fields .Boolean ()
29
41
garden_area = fields .Integer (string = "Garden Area (sqm)" )
30
42
active = fields .Boolean (default = True )
31
- garden_orientation = fields .Selection ([
32
- ('north' ,'North' ),
33
- ('south' ,'South' ),
34
- ('east' ,'East' ),
35
- ('west' ,'West' )
36
- ],string = "Garden Orientation" )
37
- state = fields .Selection (
38
- [
39
- ('new' , 'New' ),
40
- ('offer_received' , 'Offer Received' ),
41
- ('offer_accepted' , 'Offer Accepted' ),
42
- ('sold' , 'Sold' ),
43
- ('cancelled' , 'Cancelled' )
44
- ],
45
- required = True ,
46
- copy = False ,
47
- default = 'new' )
48
- property_type_id = fields .Many2one (
49
- "estate.property.types" , string = "Property Type"
43
+ garden_orientation = fields .Selection (
44
+ [("north" , "North" ), ("south" , "South" ), ("east" , "East" ), ("west" , "West" )],
45
+ string = "Garden Orientation" ,
50
46
)
51
- buyer_id = fields .Many2one (
52
- "res.partner" , string = "Buyer" , copy = False
47
+ state = fields .Selection (
48
+ [
49
+ ("new" , "New" ),
50
+ ("offer_received" , "Offer Received" ),
51
+ ("offer_accepted" , "Offer Accepted" ),
52
+ ("sold" , "Sold" ),
53
+ ("cancelled" , "Cancelled" ),
54
+ ],
55
+ required = True ,
56
+ copy = False ,
57
+ default = "new" ,
53
58
)
59
+ property_type_id = fields .Many2one ("estate.property.types" , string = "Property Type" )
60
+ buyer_id = fields .Many2one ("res.partner" , string = "Buyer" , copy = False )
54
61
salesperson_id = fields .Many2one (
55
62
"res.users" , string = "Salesperson" , default = lambda self : self .env .user
56
63
)
57
- tag_ids = fields .Many2many (' estate.property.tags' , string = "Tags" )
64
+ tag_ids = fields .Many2many (" estate.property.tags" , string = "Tags" )
58
65
59
- offer_ids = fields .One2many (' estate.property.offer' , ' property_id' , string = "Offers" )
66
+ offer_ids = fields .One2many (" estate.property.offer" , " property_id" , string = "Offers" )
60
67
61
- best_price = fields .Float (compute = ' _get_best_offer_price' , store = True )
68
+ best_price = fields .Float (compute = " _get_best_offer_price" , store = True )
62
69
63
- @api .depends ("living_area" ,"garden_area" )
70
+ @api .ondelete (at_uninstall = False )
71
+ def _unlink_except_state_new_or_cancelled (self ):
72
+ for record in self :
73
+ if record .state not in ["new" , "cancelled" ]:
74
+ raise UserError (
75
+ _ ("You can only delete properties in 'New' or 'Cancelled' state." )
76
+ )
77
+
78
+ @api .depends ("living_area" , "garden_area" )
64
79
def _compute_total_area (self ):
65
80
for record in self :
66
81
record .total_area = record .living_area + record .garden_area
67
-
68
- @api .depends (' offer_ids.price' )
82
+
83
+ @api .depends (" offer_ids.price" )
69
84
def _get_best_offer_price (self ):
70
85
for record in self :
71
- prices = record .offer_ids .mapped (' price' )
86
+ prices = record .offer_ids .mapped (" price" )
72
87
record .best_price = max (prices ) if prices else 0.0
73
88
74
- @api .onchange (' garden' )
89
+ @api .onchange (" garden" )
75
90
def _onchange_garden (self ):
76
91
for record in self :
77
92
if record .garden :
78
93
record .garden_area = 10
79
- record .garden_orientation = ' north'
94
+ record .garden_orientation = " north"
80
95
else :
81
96
record .garden_area = 0
82
- record .garden_orientation = ''
97
+ record .garden_orientation = ""
83
98
84
99
def action_set_state_sold (self ):
85
100
for record in self :
86
- if ( record .state == ' cancelled' ) :
101
+ if record .state == " cancelled" :
87
102
raise UserError (_ ("Cancelled property cannot be sold." ))
88
103
else :
89
- record .state = ' sold'
104
+ record .state = " sold"
90
105
return True
91
106
92
107
def action_set_state_cancel (self ):
93
108
for record in self :
94
- if ( record .state == ' sold' ) :
109
+ if record .state == " sold" :
95
110
raise UserError (_ ("Sold property cannot be cancelled." ))
96
111
else :
97
- record .state = ' cancelled'
112
+ record .state = " cancelled"
98
113
return True
99
-
100
- @api .constrains (' selling_price' , ' expected_price' )
114
+
115
+ @api .constrains (" selling_price" , " expected_price" )
101
116
def _check_selling_price (self ):
102
117
for record in self :
103
- if not float_is_zero (record .selling_price ,precision_digits = 2 ):
104
- if float_compare (
105
- record .selling_price ,
106
- record .expected_price * 0.9 ,
107
- precision_digits = 2 ) < 0 :
108
- raise ValidationError (_ ("The selling price cannot be lower than 90% of the expected price" ))
109
-
110
-
118
+ if not float_is_zero (record .selling_price , precision_digits = 2 ):
119
+ if (
120
+ float_compare (
121
+ record .selling_price ,
122
+ record .expected_price * 0.9 ,
123
+ precision_digits = 2 ,
124
+ )
125
+ < 0
126
+ ):
127
+ raise ValidationError (
128
+ _ (
129
+ "The selling price cannot be lower than 90% of the expected price"
130
+ )
131
+ )
0 commit comments