1
1
from dateutil .relativedelta import relativedelta
2
2
from odoo import fields , models , api , _
3
3
from odoo .exceptions import UserError , ValidationError
4
- from odoo .tools .float_utils import float_compare , float_is_zero , float_round
5
-
6
-
4
+ from odoo .tools .float_utils import float_compare , float_is_zero
7
5
8
6
9
7
class RecurringPlan (models .Model ):
10
8
_name = "estate.property"
11
9
_description = "estate property revenue plans"
12
- _order = "id desc" # For ordering in ascending opr descending order one more way to do so is from view like: <list default_order="date desc">
10
+ _order = "id desc" # For ordering in ascending opr descending order one more way to do so is from view like: <list default_order="date desc">
13
11
14
12
name = fields .Char (required = True )
15
13
description = fields .Text (string = "Description" )
16
14
postcode = fields .Char (string = "Postcode" )
17
- date_availability = fields .Date (string = "Available From" , copy = False , default = lambda self : fields .Date .today () + relativedelta (months = 3 ))
15
+ date_availability = fields .Date (
16
+ string = "Available From" ,
17
+ copy = False ,
18
+ default = lambda self : fields .Date .today () + relativedelta (months = 3 ),
19
+ )
18
20
expected_price = fields .Float (string = "Expected Price" , required = True )
19
21
selling_price = fields .Float (string = "Selling Price" , readonly = True , copy = False )
20
22
bedrooms = fields .Integer (string = "Bedrooms" , default = 2 )
@@ -25,94 +27,104 @@ class RecurringPlan(models.Model):
25
27
garden_area = fields .Integer (string = "Garden Area (sqm)" )
26
28
garden_orientation = fields .Selection (
27
29
selection = [
28
- (' north' , ' North' ),
29
- (' south' , ' South' ),
30
- (' east' , ' East' ),
31
- (' west' , ' West' )
30
+ (" north" , " North" ),
31
+ (" south" , " South" ),
32
+ (" east" , " East" ),
33
+ (" west" , " West" ),
32
34
],
33
- string = ' Garden Orientation' ,
34
- help = "Orientation of the garden relative to the property"
35
+ string = " Garden Orientation" ,
36
+ help = "Orientation of the garden relative to the property" ,
35
37
)
36
38
active = fields .Boolean (default = True )
37
39
state = fields .Selection (
38
40
selection = [
39
- (' new' , ' NEW' ),
40
- (' offer_received' , ' Offer Received' ),
41
- (' offer_accepted' , ' Offer Accepted' ),
42
- (' sold' , ' Sold' ),
43
- (' cancelled' , ' Cancelled' )
41
+ (" new" , " NEW" ),
42
+ (" offer_received" , " Offer Received" ),
43
+ (" offer_accepted" , " Offer Accepted" ),
44
+ (" sold" , " Sold" ),
45
+ (" cancelled" , " Cancelled" ),
44
46
],
45
47
string = "Status" ,
46
- required = True ,
47
- default = ' new' ,
48
+ required = True ,
49
+ default = " new" ,
48
50
copy = False ,
49
51
# readonly=True
50
-
51
52
)
52
53
53
54
total_area = fields .Integer (string = "Total Area" , compute = "_compute_total_area" )
54
55
best_price = fields .Float (string = "Best Offer" , compute = "_compute_best_price" )
55
56
56
57
property_type_id = fields .Many2one ("estate.property.type" , string = "Property Type" )
57
58
buyer_id = fields .Many2one ("res.partner" , string = "Buyer" , copy = False )
58
- user_id = fields .Many2one ("res.users" , string = "Salesman" , copy = False , default = lambda self : self . env . user )
59
-
60
- tag_id = fields . Many2many ( "estate.property.tag" , string = "Tags" , copy = False )
59
+ user_id = fields .Many2one (
60
+ "res.users" , string = "Salesman" , copy = False , default = lambda self : self . env . user
61
+ )
61
62
62
- offer_id = fields .One2many ("estate.property.offer" , "property_id" , string = "Offer" )
63
+ tag_id = fields .Many2many ("estate.property.tag" , string = "Tags" , copy = False )
63
64
65
+ offer_id = fields .One2many ("estate.property.offer" , "property_id" , string = "Offer" )
64
66
65
67
_sql_constraints = [
66
- ('check_expected_price' , 'CHECK(expected_price > 0)' ,'The Expected price of a property should be strictly positive.' ),
67
- ('check_selling_price' , 'CHECK(selling_price IS NULL OR selling_price >= 0)' , 'Selling price must be positive when set.' )
68
+ (
69
+ "check_expected_price" ,
70
+ "CHECK(expected_price > 0)" ,
71
+ "The Expected price of a property should be strictly positive." ,
72
+ ),
73
+ (
74
+ "check_selling_price" ,
75
+ "CHECK(selling_price IS NULL OR selling_price >= 0)" ,
76
+ "Selling price must be positive when set." ,
77
+ ),
68
78
]
69
79
70
-
71
- @api .depends ('living_area' , 'garden_area' )
80
+ @api .depends ("living_area" , "garden_area" )
72
81
def _compute_total_area (self ):
73
82
for area in self :
74
83
area .total_area = area .living_area + area .garden_area
75
84
76
-
77
- @api .depends ('offer_id.price' )
85
+ @api .depends ("offer_id.price" )
78
86
def _compute_best_price (self ):
79
87
for record in self :
80
88
# Get all prices from offer_ids
81
- offer_prices = record .offer_id .mapped (' price' )
89
+ offer_prices = record .offer_id .mapped (" price" )
82
90
record .best_price = max (offer_prices ) if offer_prices else 0.0
83
91
84
-
85
92
@api .onchange ("garden" )
86
93
def _onchange_garden (self ):
87
- if ( self .garden ) :
88
- self .garden_orientation = ' north'
94
+ if self .garden :
95
+ self .garden_orientation = " north"
89
96
self .garden_area = 10
90
97
else :
91
98
self .garden_orientation = False
92
99
self .garden_area = 0
93
-
94
- def action_property_sold (self ):
95
- for prop in self :
96
- if prop .state == ' cancelled' :
100
+
101
+ def action_property_sold (self ):
102
+ for prop in self :
103
+ if prop .state == " cancelled" :
97
104
raise UserError (_ ("Cancelled properties cannot be sold." ))
98
- prop .state = ' sold'
99
- return True
105
+ prop .state = " sold"
106
+ return True
100
107
101
108
def action_property_cancel (self ):
102
109
for prop in self :
103
- if prop .state == ' sold' :
110
+ if prop .state == " sold" :
104
111
raise UserError (_ ("Sold properties cannot be cancelled." ))
105
- prop .state = ' cancelled'
112
+ prop .state = " cancelled"
106
113
return True
107
114
108
- @api .constrains (' selling_price' , ' expected_price' )
115
+ @api .constrains (" selling_price" , " expected_price" )
109
116
def _check_selling_price (self ):
110
117
for record in self :
111
118
if float_is_zero (record .selling_price , precision_digits = 2 ):
112
119
continue
113
120
min_allowed_price = record .expected_price * 0.9
114
121
115
- if float_compare (record .selling_price , min_allowed_price , precision_digits = 2 ) < 0 :
122
+ if (
123
+ float_compare (
124
+ record .selling_price , min_allowed_price , precision_digits = 2
125
+ )
126
+ < 0
127
+ ):
116
128
raise ValidationError (
117
129
"Selling price cannot be lower than 90% of the expected price. "
118
130
f"(Minimum allowed: { min_allowed_price :.2f} )"
@@ -121,5 +133,9 @@ def _check_selling_price(self):
121
133
@api .ondelete (at_uninstall = False )
122
134
def _unlink_except_state_not_new (self ):
123
135
for rec in self :
124
- if rec .state not in ['new' , 'cancelled' ]:
125
- raise UserError (_ ("You cannot delete a property unless its state is 'New' or 'Cancelled'." ))
136
+ if rec .state not in ["new" , "cancelled" ]:
137
+ raise UserError (
138
+ _ (
139
+ "You cannot delete a property unless its state is 'New' or 'Cancelled'."
140
+ )
141
+ )
0 commit comments